What is DevSecOps?
DevSecOps is the practice of weaving security into every stage of building and running software, instead of treating it as a final checkbox before launch. The name is a blend of Dev (development), Sec (security), and Ops (operations) — it says security is everyone’s job, not a separate team you call at the end. For someone learning to run Ubuntu servers, this matters a lot: most servers get hacked not because of some clever zero-day attack, but because of boring, preventable mistakes like an open port, a weak password, or an unpatched package. DevSecOps is the mindset that catches those mistakes early.
What DevSecOps actually means
Traditional software delivery treated security as a gate at the very end. Developers wrote code, operations deployed it, and then — sometimes weeks later — a security team scanned it and sent back a list of problems. By then the bad decisions were already baked in, expensive to fix, and often shipped to production anyway because of deadline pressure.
DevSecOps flips that. It says: build security checks into the same automated pipeline you already use for testing and deploying. If a developer commits a hard-coded password, the pipeline should fail immediately — not three weeks later in an audit. Security becomes continuous and automatic, the same way running unit tests is.
Security that depends on a human remembering to do it will eventually be forgotten. The whole point of DevSecOps is to make the secure path the automatic path.
The “shift left” idea
You will hear the phrase “shift left” constantly. Imagine your delivery process drawn as a timeline left-to-right: write code → test → build → deploy → run in production. “Shifting left” means moving security checks toward the start (the left) of that line, so problems are caught when they are cheapest to fix.
A bug found while you are still typing the code costs almost nothing to fix. The same bug found after it is running in production — exposed to real users and attackers — can cost a weekend of emergency work, a data breach, or worse. The earlier you catch it, the cheaper it is.
| Where the issue is found | Relative cost to fix | Example |
|---|---|---|
| In the editor / on commit | Lowest | Linter flags a hard-coded API key |
| In the CI pipeline | Low | Dependency scanner finds a vulnerable library |
| In staging / pre-production | Medium | Penetration test finds an open admin endpoint |
| In production | Highest | Attacker exploits an unpatched server |
When to shift left: always — for code scanning, dependency checks, and secret detection. These are cheap to automate and catch the most common mistakes. When NOT to over-do it: do not block every commit on a slow, full security scan that takes 40 minutes. Run fast checks on every commit, and save the heavy, slow scans for nightly runs so developers are not stuck waiting.
Shared security ownership
The older model had a clear (and unhealthy) split: “developers build it, the security team secures it.” DevSecOps replaces that with shared ownership — everyone who touches the system owns some piece of its security.
- Developers write code that validates input, avoid hard-coded secrets, and keep dependencies up to date.
- Operations / server admins harden the servers, configure the firewall, and keep the OS patched.
- Security specialists stop being gatekeepers and instead become coaches — they build the automated tooling, write the secure defaults, and teach the other teams.
On a single Ubuntu server you manage yourself, you are all three roles. That is actually great news: it means you can apply every layer without waiting on anyone.
A concrete first taste
DevSecOps is a mindset, but it shows up as real commands. Here is the kind of basic hardening you would automate. First, make sure your Ubuntu server installs security patches by itself:
sudo apt update
sudo apt install -y unattended-upgrades
sudo systemctl enable --now unattended-upgrades
Output:
Reading package lists... Done
unattended-upgrades is already the newest version (2.9.1+nmu4ubuntu1).
Synchronizing state of unattended-upgrades.service with SysV service script...
Next, check that no unexpected services are listening on the network — open ports are how attackers get in:
sudo ss -tulnp
Output:
Netid State Recv-Q Send-Q Local Address:Port Process
tcp LISTEN 0 128 0.0.0.0:22 users:(("sshd",pid=812))
tcp LISTEN 0 511 0.0.0.0:80 users:(("nginx",pid=940))
tcp LISTEN 0 128 127.0.0.1:5432 users:(("postgres",pid=701))
Here you want to see only the ports you expect: 22 for SSH, 80 for the web server, and PostgreSQL listening on 127.0.0.1 (localhost only — good, it is not exposed to the internet). Anything surprising on 0.0.0.0 deserves investigation.
How this fits the rest of these docs
This page is the “why.” The pages that follow are the “how” — each one is a practical hardening step you can apply today on Ubuntu 22.04 or 24.04 LTS:
- Locking down the server and SSH (the remote-login service) so only you can get in.
- Configuring
ufw(Uncomplicated Firewall, Ubuntu’s simple firewall tool) to close every door you are not using. - Adding
fail2banto automatically ban attackers who keep guessing passwords. - Managing secrets so passwords and keys never end up in your code.
- Setting up TLS (Transport Layer Security, the encryption behind HTTPS) so traffic cannot be read in transit.
- Scanning for known vulnerabilities and keeping packages patched.
Read them in order, or jump to whichever risk worries you most.
Best Practices
- Automate the secure path. If a check can be a script in your pipeline, make it one — humans forget, scripts do not.
- Patch continuously, not occasionally. Enable
unattended-upgradesso security fixes land without you remembering. - Default to least exposure. Close every port, disable every service, and remove every permission you do not actively need.
- Never store secrets in code or in Git. Use environment files with strict permissions or a secrets manager.
- Layer your defenses. A firewall, key-only SSH, and
fail2bantogether are far stronger than any one alone. - Treat security findings like build failures. A failed scan should stop a deploy the same way a failed test does.
- Keep an audit trail. Centralize logs in
/var/logand review them, so you can tell when something is wrong.