Skip to main content

Pipeline security, OIDC & DORA feedback

A pipeline is one of the most privileged things in your whole system — it can build, sign, and ship code to production. That makes it a prime target, and how it authenticates and handles secrets is a security question of the first order. This lesson covers the modern answers: OIDC federation for keyless cloud auth, short-lived credentials instead of stored keys, sealed/external secrets so secrets can safely live alongside Git-as-source-of-truth, and automated dependency updates. Then it closes the chapter's feedback loop with DORA — the four metrics that tell you whether all of this is actually making you faster and safer.

The secrets problem: never hardcode, never store long-lived keys

The first rule is absolute: never hardcode a secret in your pipeline or repo. An API key committed to Git is compromised — Git history is forever, and bots scan public repos within seconds. But the more interesting modern shift is away from storing secrets in CI at all.

The old pattern: paste a long-lived cloud access key (one that never expires) into your CI system's secret store, and the pipeline uses it to deploy. The problem: that key is a permanent, high-value target. If your CI is breached — or a malicious dependency in a build runs env — that key is exfiltrated and works forever, from anywhere. Storing long-lived cloud keys as CI secrets is now considered an anti-pattern.

OIDC federation: keyless cloud auth

The modern replacement is OIDC federation (OpenID Connect). Instead of storing a credential, the pipeline proves its identity to the cloud at run time and gets a short-lived token in return.

Here's the flow, traced:

CI job\n(e.g. GitHubActions)Cloud(AWS/GCP/Azure)\ntrust policyCloud resourcessigned identitytoken:\n'I am repoX, branch main'verifies +issues\nshort-livedcredential\n(expiresdeploy with tempcreds
  1. The cloud is configured to trust your CI provider's identity tokens, scoped narrowly: "trust tokens from GitHub Actions, but only for this repository and this branch."
  2. When the pipeline runs, the CI provider issues a signed identity token describing the job ("I am repo X, workflow Y, branch main").
  3. The cloud verifies that token against its trust policy and, if it matches, issues a short-lived credential (valid for minutes).
  4. The pipeline deploys with that temporary credential, which expires almost immediately afterward.

The payoff is large: there is no long-lived key to store, leak, or steal. Nothing in your CI secret store to exfiltrate; a stolen token is useless within minutes; and access is scoped to the exact repo/branch. This is keyless auth, and it's the current best practice for CI-to-cloud authentication across GitHub-to-cloud federation and equivalents.

:::note Short-lived credentials, generally The principle beneath OIDC is short-lived credentials: prefer a credential that expires in minutes, minted on demand, over one that lives forever in a vault. Short-lived creds shrink the window of exposure to near zero — even if leaked, they're dead almost immediately. This is the same instinct as immutable artifacts: remove the durable, mutable, stealable thing. :::

Secrets in a GitOps world: sealed and external secrets

GitOps says everything lives in Git (lesson 5.5) — but you obviously can't commit a raw database password to a repo. Two patterns reconcile "Git as source of truth" with "never put plaintext secrets in Git":

  • Sealed Secrets — You encrypt the secret before committing it. A controller in the cluster holds the private key and is the only thing that can decrypt it. So Git stores a SealedSecret — ciphertext that's safe to commit publicly — and the in-cluster controller turns it into a real Kubernetes Secret at apply time. The secret is in Git, but only as something useless to anyone without the cluster's key.
  • External Secrets Operator — You commit only a reference ("the prod DB password lives in this slot of AWS Secrets Manager / Vault"), not the value. An operator in the cluster reads the reference, fetches the real secret from the external manager, and creates the Kubernetes Secret. Git holds a pointer; the actual secret lives in a dedicated secrets manager.
Git: encryptedSealedSecretcontrollerdecrypts\nin clusterGit: reference onlyoperatorfetches\nfromVault/Secrets Mgr

Both let you keep the GitOps promise — desired state fully in Git — without ever exposing a plaintext secret. (Recall from Chapter 4 that a plain Kubernetes Secret is only base64-encoded, not encrypted; these patterns are what protect the actual values.)

Automating dependencies: Renovate and Dependabot

A quieter pipeline-security practice: keep dependencies current automatically. Renovate and Dependabot watch your dependency manifests and open pull requests when a dependency has a new version — especially a security fix. Each PR runs through your full pipeline (test, scan), so updates are verified before merge. This keeps the supply chain (lesson 5.3) patched without a human manually tracking hundreds of libraries, and pairs naturally with trunk-based development's small, frequent changes.

Closing the loop: the DORA metrics

How do you know any of this is working? The industry-standard answer is DORA (from the DevOps Research and Assessment program) — four metrics that measure delivery performance, balancing speed against stability:

SpeedDeployment Frequency\nhow often you shipLead Time for Changes\ncommit → productionStabilityChange Failure Rate\n% of deploys causing a problemMTTR / Time to Restore\nhow fast you recover
  • Deployment Frequency — how often you deploy to production. Higher (smaller, more frequent) is better.
  • Lead Time for Changes — how long from a commit landing to it running in production. Shorter is better.
  • Change Failure Rate — what percentage of deployments cause a failure (incident, rollback, hotfix). Lower is better.
  • MTTR (Mean Time To Restore) — when something breaks, how fast you recover. Shorter is better.

The crucial insight: the speed metrics and the stability metrics move together in healthy teams. Small, frequent changes (trunk-based development) with strong gates (tests, scans), safe rollouts (progressive delivery), and instant rollback (GitOps revert) make you both faster and more reliable — speed and safety aren't a trade-off when the pipeline is good.

DORA becomes a feedback loop when you wire these measurements back into how you run the pipeline: track them continuously, and when change failure rate climbs or lead time stretches, that's the signal to fix a gate, tighten a canary analysis, or shorten a branch. The pipeline doesn't just ship — it measures its own delivery health and tells you where to improve. (Measuring all four depends on the observability of Chapter 6.)

:::tip Durable vs dated OIDC/keyless auth, short-lived credentials, keeping plaintext secrets out of Git, and the DORA metrics are durable — they're principles of least privilege, minimized exposure, and measured delivery. The tools (the specific OIDC setup, Sealed Secrets vs External Secrets Operator, Renovate vs Dependabot) are dated. Map each to its principle — prove identity instead of storing keys; reference or encrypt secrets instead of committing them; measure speed and stability together — and tool changes are cosmetic. :::

Common pitfalls

  • Long-lived cloud keys as CI secrets. A permanent, stealable, works-from-anywhere credential. Use OIDC federation for short-lived, scoped, keyless auth.
  • Hardcoding any secret in repo or pipeline. Committed secrets are compromised instantly. Never commit a raw secret — encrypt it (Sealed Secrets) or reference it (External Secrets).
  • Plaintext secrets in a GitOps repo. "Everything in Git" does not mean raw passwords in Git. Sealed/external secrets reconcile the two.
  • Optimizing speed or stability in isolation. Chasing deployment frequency while ignoring change failure rate burns you. DORA's four metrics are read together; healthy teams improve both.
  • Measuring DORA but never acting on it. Metrics on a dashboard nobody uses change nothing. The value is the feedback loop — let the numbers drive concrete pipeline fixes.

Why it matters

A pipeline is highly privileged, so how it authenticates is a top-tier security decision: never hardcode secrets, and stop storing long-lived cloud keys in CI — use OIDC federation so the pipeline proves its identity and receives a short-lived, scoped credential with nothing durable to steal. In a GitOps world, Sealed Secrets (encrypt before committing) and the External Secrets Operator (commit only a reference) keep plaintext secrets out of Git while preserving Git-as-source-of-truth, and Renovate/Dependabot keep the supply chain patched automatically. Finally, the DORA metrics — deployment frequency and lead time (speed), change failure rate and MTTR (stability) — close the chapter's feedback loop: wired back into the pipeline, they show that small frequent changes with strong gates make you faster and safer at once. That's the full arc — commit to running service, automatically, repeatably, and safely. Time to lock it in.

Next: Chapter 5 checkpoint →