DevOps Interview Questions: Config and Secrets Management
Reviewed by Mark Dickie · Last updated
6 questions on this page you can answer and see marked on the spot. Go to the first one
DevOps config and secrets management is the practice of keeping passwords, API keys, and certificates out of source code and giving workloads only the values they need at runtime. Interviewers expect you to separate plain configuration from secrets, name where each value lives in a running system, and explain how it gets rotated. The quiz below covers environment variables, HashiCorp Vault, Kubernetes Secrets, and cleaning a credential out of Git history.
Which secrets tools do DevOps interviewers expect you to compare?
| Mechanism | What to know | Failure to watch for |
|---|---|---|
| Environment variables | 12-factor config read at process start; visible through docker inspect and /proc/<pid>/environ | Values echoed into CI logs or crash dumps |
| Kubernetes Secrets | Base64-encoded, not encrypted, unless an EncryptionConfiguration is set on kube-apiserver | Any subject with get on secrets in the namespace can read them |
| HashiCorp Vault | Dynamic database credentials issued with a lease and TTL, revoked when the lease ends | A long-lived root token left in a CI variable |
| AWS Secrets Manager | Built-in rotation through a rotation Lambda function, with staging labels AWSCURRENT and AWSPREVIOUS | The app caches the value at startup and keeps using the old one after rotation |
| SOPS or Sealed Secrets | Encrypted values committed to Git, decrypted by a key held in the cluster or KMS | The decryption key stored beside the encrypted file |
Hands-on exercises worth doing before the interview:
- Commit a dummy
.envfile, remove it withgit filter-repo, then rotate the key as if it had leaked. - Run a pod with the Vault Agent sidecar, fetch a dynamic database credential, and confirm the lease expires on schedule.
- Add an EncryptionConfiguration for
secretsto kube-apiserver, then check withetcdctlthat the stored value is no longer readable as plain text. - Rotate an AWS Secrets Manager secret and check whether the application picks up the new value without a restart.
Key facts
- Tarmac has 25 DevOps interview questions on this topic, 10 of them on this page, at difficulty 1–5 of 5.
- Tarmac tracked 2,502 job postings asking for DevOps in October 2026.
- Roles asking for DevOps advertise a median base salary of £78,000, across 823 job postings as of October 2026.
- Tarmac last reviewed these DevOps interview questions on 9 November 2026.
At a glance
| Questions | 10 shown · 25 in the bank |
|---|---|
| Difficulty | 1–5 of 5 |
| Formats | Multiple choice, Multiple answer, True / false, Code output, Flashcard, Find the bug, Short answer, Design exercise, Ordering, Fill in the blank |
What you'll review
- config management
- secret management
- idempotency
Practice questions
Try one before you open the answer. Pick an option and press Check; it's marked on the spot.
Which approach is the recommended way to manage sensitive configuration values such as database passwords and API keys in a modern DevOps pipeline?#
Options
Show answer
Store secrets such as database passwords and API keys in a dedicated secrets manager like HashiCorp Vault or AWS Secrets Manager, and inject them into the application at runtime. This keeps secrets encrypted at rest, access-controlled via policies, and out of source control, whereas hard-coding them or committing plaintext config files exposes credentials and makes rotation difficult.
Secrets should never live in source code, version-controlled config files, or shared documents because those media expose credentials to anyone with access and make rotation difficult. A secrets manager encrypts secrets at rest, controls access via policies, and injects them into the runtime environment (env vars, mounted files, etc.) so the application never sees them committed in plaintext.
Which of the following are recommended practices for handling application secrets such as database passwords and API tokens? Select all that apply.#
Options
Pick every one that applies.
Show answer
Good secret management keeps credentials out of source code and Git history. Teams store secrets in a dedicated secrets manager and inject them at runtime, rotate them regularly and after any suspected exposure, and grant read access only to the workloads that need each secret.
The recommended practices are storing secrets in a dedicated secrets manager and injecting them at runtime, rotating them regularly and after suspected exposure, and scoping read access to the workloads that need each secret (least privilege). Hard-coding secrets in source code and committing a .env file to Git, even to a private repository, are wrong because anyone with repository access, and every past clone or history copy, gets the credential, and removing it from history does not make it safe to reuse.
True or false: if an API key was committed and pushed to a shared Git repository, and a later commit removes the key from the files, the key no longer needs to be rotated because it is no longer in the repository.#
Options
Show answer
The statement is false. A later commit that removes the key from the working files does not erase it from Git history, so the key remains visible in past commits and in every existing clone or fetch that already contains it. The key must still be treated as compromised: revoke it, rotate it, and optionally purge it from history.
The statement is false. Git retains every past commit, so the key still exists in the repository history and in any clone or fetch that already contains it. Anyone who pulled the repository before the removal can still read the key from prior commits. Because the secret must be treated as compromised, removing it from the latest commit alone is not sufficient — the correct response is to revoke and rotate the key, and optionally rewrite history to purge it.
A twelve-factor app reads config from the environment, falling back to a checked-in default. The container is started with DATABASE_URL set in its environment to postgres://prod-db/app, while the repo's committed .env.defaults file sets DATABASE_URL=postgres://localhost/app. The startup code is below. Which database does the app connect to, and why?#
// load committed defaults first, then let the real environment win
const defaults = parseEnvFile('.env.defaults');
const config = { ...defaults, ...process.env };
connect(config.DATABASE_URL);Options
Show answer
postgres://prod-db/app — the spread merges process.env last, so the real environment variable overrides the committed default, which is the twelve-factor pattern
Object spread merges left to right, and on a key collision the last spread wins. { ...defaults, ...process.env } therefore lets any variable present in the real environment override the committed default — so DATABASE_URL resolves to postgres://prod-db/app. This is the twelve-factor 'store config in the environment' principle in miniature: the same artifact ships everywhere, and per-environment values (prod DB, secrets, feature toggles) come from the environment at runtime, while a committed defaults file gives a sane local-dev fallback that never contains real secrets. The claim that committed defaults always take precedence over environment variables inverts the precedence (committed defaults are the fallback, not the override). The claim that it throws is wrong — duplicate keys across the two sources is the normal, intended case, not an error. The claim that process.env is read-only and cannot override a value loaded from a file is false: process.env is a readable map here and nothing about reading it from a file changes merge order. The interview point is that environment beats baked-in defaults, which is what keeps one build deployable to every environment.
In secret management, what is secret rotation, and why is it preferred over relying on a single long-lived credential that is never changed?#
Show answer
Secret rotation is the practice of periodically (or on demand) replacing a secret, such as a database password, API key, or certificate, with a new value and retiring the old one. Rotation limits the window of exposure: if a credential leaks, it becomes useless after the next rotation, and rotation forces systems to fetch secrets dynamically rather than hard-coding them. Long-lived static credentials that never change mean a leak stays exploitable indefinitely and is hard to detect or revoke safely.
Rotation bounds how long a leaked credential remains valid and makes revocation a routine operation rather than an emergency. A strong answer names periodic or on-demand replacement of the secret, the reduced exposure window after a leak, and the need for consumers to retrieve secrets dynamically (not baked into images or config) so rotation does not cause outages.
This provisioning script is run by the configuration-management tool on every converge to ensure an 'app' user and its config line exist. It works the first time, but re-running it on an already-provisioned host fails or corrupts the file. Why is it not idempotent, and what is the fix?#
#!/usr/bin/env bash
set -euo pipefail
# create the service account
useradd app
# ensure the app reads from the shared config dir
echo 'CONFIG_DIR=/etc/app' >> /etc/app.envOptions
Show answer
Both operations assume a clean host: useradd app errors (and aborts under set -e) when the user already exists, and the >> append adds a duplicate CONFIG_DIR line every run — the script must check-then-act (e.g. id app || useradd app) and write the line only if absent, so repeated runs converge to the same state
Idempotency means running the operation any number of times leaves the system in the same end state as running it once — the contract a convergent config tool depends on, since it re-applies on every run. This script breaks that contract twice. useradd app is a create that fails with a non-zero exit when the user already exists; under set -e that aborts the whole converge on the second run. And echo ... >> /etc/app.env appends, so each run adds another identical CONFIG_DIR=/etc/app line, growing the file and potentially changing how the app parses it. The fix is to make every step check-then-act so it's safe to repeat: guard the user creation (id app >/dev/null 2>&1 || useradd app) and add the config line only if it isn't already present (grep -qxF 'CONFIG_DIR=/etc/app' /etc/app.env || echo 'CONFIG_DIR=/etc/app' >> /etc/app.env). The claim that removing set -euo pipefail makes the script idempotent is backwards — set -e correctly surfaces the latent failure; deleting it just hides a broken converge. The claim that useradd should be usermod fixes only half the problem and wrongly calls the append idempotent. The claim that nothing is wrong is plainly false on both counts.
Name the main anti-patterns in handling application secrets (API keys, DB passwords) and what a sound secret-management approach does instead.#
Show answer
The cardinal anti-pattern is committing secrets into source control — even in a private repo they live forever in git history and leak through forks, clones, and CI logs. Related anti-patterns: hardcoding secrets in the application image so every copy of the artifact carries them, baking them into Dockerfiles or build args, printing them to logs, sharing one static credential across all environments, and never rotating them. A sound approach keeps secrets out of code and out of the artifact entirely. They live in a dedicated secret store or vault (or the cloud provider's secret manager), are injected at deploy/runtime via environment variables or mounted files, and are scoped per environment with least-privilege access controls and audit logging. Crucially, secrets should be rotatable — short-lived or dynamically issued credentials limit the damage of a leak — and a leaked secret must be revoked and rotated, not just deleted from the latest commit, because the history still holds it.
Interviewers probe secret hygiene because the failure modes are common and costly. The headline anti-pattern is committing secrets to version control: git history is permanent, so a secret that ever touched a commit is exposed via every clone, fork, and the reflog even after you 'delete' it — which is why a leaked secret must be revoked and rotated, not merely removed from HEAD. Adjacent anti-patterns are hardcoding secrets into the application image or build args (every artifact copy now carries them), logging them, and reusing one un-rotated static credential everywhere. The sound model: keep secrets out of code and out of the build artifact, store them in a dedicated vault or cloud secret manager, inject them at deploy/runtime through environment variables or mounted files, scope them per environment with least-privilege access and an audit trail, and make them rotatable — ideally short-lived or dynamically issued so a leak has a small blast radius. A strong answer pairs the 'never in git/never in the image' rule with vault + runtime injection + rotation/revocation.
You are the platform lead for a SaaS company running 20+ microservices on Kubernetes across three clusters: dev, staging, and prod. Each service has per-environment configuration (feature flags, resource limits, endpoint URLs) and per-environment secrets (database credentials, third-party API keys, TLS certificates). The company is pursuing SOC 2 compliance, which requires encryption at rest, access auditing, and least-privilege access controls. Several services are event-driven and configured to scale to zero when idle.#
Show answer
We would use a tiered approach: non-sensitive configuration (feature flags, endpoint URLs, resource defaults) stored in a GitOps-managed ConfigMap repository (e.g., Argo CD + Kustomize overlays per environment), while all secrets are stored in HashiCorp Vault (or AWS Secrets Manager if already on AWS).
Storage & Encryption (c1): Vault provides encryption at rest via its storage backend (e.g., integrated Raft with AES-256), Shamir's secret sharing for unseal keys, and a sealed/unsealed model. Raw Kubernetes Secrets are only base64-encoded — they are not encrypted at rest unless you configure a KMS provider with encryption-at-rest (which many clusters do not enable). Relying on raw K8s Secrets fails SOC 2 requirements for encryption-at-rest and granular audit. We would use Vault as the source of truth and sync secrets into K8s Secrets only as a transient delivery vehicle, or mount them directly via CSI.
Environment Isolation & Access Control (c2): Each environment gets its own Vault namespace (or path prefix, e.g., secret/dev/, secret/staging/, secret/prod/). Each cluster authenticates to Vault via Kubernetes auth backend using its own service account token, bound to a specific Vault policy that grants read access only to that environment's path. IAM/RBAC policies enforce least-privilege: a dev cluster's Vault auth role can only read secret/dev/*. All secret accesses are logged via Vault's audit devices (file or syslog) to a tamper-evident SIEM. Developers are granted read access to dev and staging paths but never prod. To allow debugging config issues without exposing secret values, non-sensitive config lives in Git (visible to all), and for staging secrets we can provide a Vault policy that allows read on metadata but not on secret data, or use a break-glass workflow with just-in-time access and automatic expiration.
Secret Delivery (c3): We use the Secrets Store CSI Driver with the Vault provider. At pod startup, the CSI driver mounts secrets as files into a tmpfs volume, fetching them from Vault using the pod's service account. This works seamlessly for scale-to-zero services because the mount happens during pod initialization — there is no long-lived sidecar process that must be running before the pod can accept traffic. An alternative like the Vault Agent sidecar adds a startup dependency (the sidecar must fetch secrets before the main container starts), which adds latency to cold starts. The External Secrets Operator is also viable: it periodically syncs Vault secrets into standard K8s Secrets, which pods consume normally — this decouples pod startup from Vault availability but introduces a window where K8s Secrets may be stale.
Rotation & Propagation (c4): For database credentials, we use Vault dynamic secrets: Vault creates short-lived database users with configurable TTLs (e.g., 1 hour). The CSI driver re-fetches the lease before expiry. For services using the External Secrets Operator sync model, rotation triggers a K8s Secret update, and we configure a Reloader or Argo CD to issue a rollout restart when the secret changes. For shared credentials used by multiple services (e.g., a third-party API key), we prefer per-service credentials where possible; if truly shared, rotation means updating the secret in Vault and triggering a coordinated rollout restart across all consuming deployments, potentially with a brief overlap where both old and new credentials are valid (dual-key rotation pattern).
This design exercise tests senior-level understanding of the full secrets management lifecycle: choosing appropriate storage backends, enforcing least-privilege access with audit trails, selecting a delivery mechanism that handles edge cases like scale-to-zero, and planning for rotation without downtime. The rubric rewards concrete, trade-off-aware answers rather than generic 'use Vault' responses.
A service reads its PostgreSQL password from a secret store. You need to rotate the database password with zero downtime. Put these steps in the correct order, first to last.#
Put these in order
Show answer
Zero-downtime database password rotation starts by creating a second valid credential in the database, then saving it to the secret store as the new version. Services are rolled out to read that version, and usage of the old credential is checked. Only after that is the old credential revoked, so no running instance is cut off mid-rotation.
Zero-downtime rotation depends on overlapping validity. The new credential must exist in the database before it can be published, so creating it comes first. It must be written to the secret store before instances can be rolled out to read it. Only after instances have switched is it safe to check that the old credential is no longer in use, and revoking it comes last. Revoking earlier would break any instance still holding the old password, causing an outage.
In envelope encryption, each secret is sealed with its own freshly generated _____, and that key is then wrapped (encrypted) by a _____ that never leaves the KMS. Name the two keys: the first is the per-object key that encrypts the payload, the second is the key that wraps it.#
Show answer
In envelope encryption, each secret is sealed with its own freshly generated data encryption key, and that key is then wrapped (encrypted) by a key encryption key that never leaves the KMS. Name the two keys: the first is the per-object key that encrypts the payload, the second is the key that wraps it.
Envelope encryption uses two layers. A unique data encryption key (DEK) encrypts the actual secret payload, so the bulk ciphertext is produced with fast symmetric crypto. That DEK is then encrypted under a key encryption key (KEK) held inside the KMS, and only the wrapped DEK is stored alongside the ciphertext. Because the KEK never leaves the KMS, it can be rotated by re-wrapping stored DEKs without re-encrypting the bulk data, which is why the two-layer structure is used.
Related interview questions
Job market
See devops salaries and hiring demand from live job postings.
The other 15 questions
This page shows 10 and marks what you pick. That's as far as a page can go. A free account opens the other 15 and keeps every answer. What you miss comes back until it's right: after a day, then at longer gaps.
Free · the whole bank · 100 answers per 30 days, each marked with written feedback