Skip to content

Twelve-Factor Apps, What Still Holds and What Changed

A service runs perfectly on one long-lived server. Its dependencies came from a package installed by hand months ago. Its configuration lives in a file beside the source. User sessions sit in process memory. Startup compiles the application, and logs disappear into a host directory that nobody remembers to collect.

The next deployment replaces that server. Startup fails on the missing package. Rollback rebuilds different bytes. Adding a second instance signs users out at random. The team has source code, but it does not have a reproducible application.

The Twelve-Factor App methodology attacks this class of failure. It replaces hidden machine assumptions with an explicit contract between an application and the platform that builds, configures, runs, and observes it.

What Twelve-Factor is

Twelve-Factor is a methodology for building service applications that can move between execution environments, deploy predictably, scale through additional processes, and keep development close enough to production to catch meaningful differences early.

It is language-neutral. It does not require microservices, containers, Kubernetes, or a particular cloud. A modular monolith can follow the factors. A Kubernetes deployment can violate nearly all of them.

The original methodology is also not a complete production-readiness standard. It says little about identity, authorization, software supply chains, disaster recovery, service-level objectives, or vulnerability response. Those concerns need additional frameworks and controls.

The application-platform contract

The factors make the boundary between application and platform narrow enough to inspect:

APPLICATION
source + declared dependencies
|
| build
v
immutable artifact
|
+-----------+-----------+
| | |
v v v
web worker admin
| | |
+-----------+-----------+
|
config + attached resources + process signals
|
v
PLATFORM
scheduling + routing + secrets + telemetry collection

The application declares what it needs, accepts deploy-specific configuration, exposes process entry points, and treats attached services as resources. The platform supplies configuration, starts processes, routes traffic, sends lifecycle signals, and collects event streams.

The running example throughout this topic is an order service with three process types:

  • Web: Accepts HTTP requests and persists orders.
  • Worker: Consumes queued work and applies retry-safe effects.
  • Admin: Runs bounded tasks such as database migrations from the same release.

One service, three ecosystems

The examples implement one contract in three public repositories. Each tagged release is runnable without cloud credentials and exposes the same web, worker, and admin responsibilities through its native toolchain.

EcosystemTested releaseProcess commandsLocal portDeterministic check
TypeScriptv1.0.2npm run start:web, npm run start:worker, npm run admin -- migrate --target 0013101npm run verify
Pythonv1.0.2web, worker, admin migrate --target 0013102uv run python scripts/check_twelve_factor.py
Gov1.0.3orders web, orders worker, orders admin migrate --target 0013103./scripts/check-twelve-factor.sh

All three accept POST /v1/orders, require an Idempotency-Key, and return accepted work through GET /v1/orders/{orderId}. The request has customerId and amountCents. The amountCents value is an integer from 1 through 99. PostgreSQL stores the order schema from db/migrations/001_orders.sql, and Redis carries jobs through orders.v1.

The configuration boundary uses the same names in every implementation: DATABASE_URL, REDIS_URL, RELEASE_ID, APP_HOST, PORT, WORKER_CONCURRENCY, SHUTDOWN_GRACE_MS, and TELEMETRY_MODE. Language-specific defaults explain the three local ports, while the behavior and failure contract stay aligned.

The twelve factors at a glance

Each factor answers a failure mode. The modern reading preserves that intent while replacing dated mechanisms where the platform contract has evolved.

FactorOriginal intentModern readingProof question
Factor I: CodebaseOne tracked codebase, many deploysTrace each release to source and a build targetCan every release be traced to an exact revision?
Factor II: DependenciesDeclare and isolate dependenciesLock, verify, and package the full dependency graphCan a clean environment install without hidden host state?
Factor III: ConfigKeep deploy config out of codeValidate deploy inputs and deliver secrets through platform boundariesDoes bad config fail safely before work starts?
Factor IV: Backing servicesTreat services as attached resourcesInject endpoints and verify provider contractsCan an attachment change without a code edit?
Factor V: Build, release, runKeep stages separatePromote one immutable, attributable artifactCan the same artifact roll forward or back without rebuilding?
Factor VI: ProcessesRun stateless, share-nothing processesPut durable state outside replaceable instancesCan an instance disappear without losing required state?
Factor VII: Port bindingExport services through a bound portExpose a self-contained invocation contractCan the platform start and route the service directly?
Factor VIII: ConcurrencyScale through the process modelScale workload types independently with bounded workCan web and worker capacity change independently?
Factor IX: DisposabilityStart fast and stop gracefullyCoordinate readiness, draining, timeouts, and retriesCan the platform stop an instance without corrupting work?
Factor X: Dev/prod parityKeep environments closeTest production-significant contracts at the cheapest faithful layerAre meaningful differences known and exercised?
Factor XI: LogsEmit logs as event streamsWrite structured events and correlate logs, metrics, and tracesCan an operator reconstruct a failure outside the instance?
Factor XII: Admin processesRun one-off tasks with the releaseUse bounded, attributable commands with the same code and configCan an admin action be tied to an identity and release?

The detailed sections use the same sequence: original principle, failure prevented, modern reading, implementation evidence, and an audit question.

Factor I: Codebase

Original claim: Factor I defines one codebase tracked in revision control with many deploys. A deploy is a running instance of the application in an environment such as production or staging.

Failure mode: A service assembled from copied directories, untracked server patches, or several unrelated source roots has no authoritative history. Teams cannot answer which code produced a running release or reproduce it after a machine fails.

Modern reading: Treat the deployable application as the unit of identity. A monorepo can contain several applications when each has an explicit build target and release history. Several repositories can contribute libraries to one application when dependency versions make the resulting source graph reproducible. Repository count is less useful than the path from release to revision.

Verify it: Pick a running web, worker, and admin process. Recover the application name, release identifier, source revision, and build target for each. All process types in one release should point to the same application revision. See Factor I: Codebase examples in TypeScript, Python, and Go.

Factor II: Dependencies

Original claim: Factor II requires explicit dependency declaration and isolation. The application cannot rely on a library or executable merely because the host operating system happens to provide it.

Failure mode: An undeclared package works on a developer laptop and fails in a clean build. A floating version resolves to different code during rollback. A runtime artifact reaches a package registry during startup and becomes unavailable when the registry or network is down.

Modern reading: A manifest declares direct dependencies. A lockfile records the resolved graph. Isolation keeps the process from importing host packages by accident. Clean installation and artifact inspection prove completeness. Integrity verification and signed provenance strengthen the supply chain, but they extend beyond the original claim.

Verify it: Install and test in an empty environment with only the manifest and lockfile available. Confirm the runtime artifact contains every required dependency and starts without compiler or registry access. See Factor II: Dependencies examples in TypeScript, Python, and Go.

Factor III: Config

Original claim: Factor III keeps values that vary between deploys out of source code. Its test is blunt and useful: the codebase should be publishable without exposing credentials or environment-specific configuration.

Failure mode: A database URL compiled into the artifact forces a rebuild for every environment. A credential committed beside source leaks through history. Scattered string lookups let an invalid value survive until the first request reaches a rarely used path.

Modern reading: Source code owns the configuration schema, defaults, and validation rules. The deployment supplies values through environment variables, mounted files, secret stores, or identity-based access. Configuration groups by independent operational concern rather than named environment bundles. Secret delivery and application configuration meet at the schema boundary, but secret material never belongs in the schema or error output.

Verify it: Start with missing and malformed values. The process should reject them before readiness without printing secret contents. Change a valid deploy setting without rebuilding the artifact. See Factor III: Config examples in TypeScript, Python, and Go.

Factor IV: Backing services

Original claim: Factor IV treats databases, queues, caches, object stores, and external APIs as attached resources. The application receives connection details through configuration instead of assuming a service lives on the same host.

Failure mode: Code embeds a production hostname, imports a provider throughout the domain layer, or depends on a daemon installed beside the application. Replacing an attachment then requires source edits and a broad rewrite.

Modern reading: Construct provider clients at the application boundary and pass narrow interfaces inward. A URL can make attachment replaceable, but it cannot make different products semantically equivalent. Transaction behavior, delivery guarantees, consistency, limits, and failure responses still need contract tests.

Verify it: Point a release at a fresh compatible resource without editing source. Run the same contract suite against both attachments and confirm that an incompatible provider fails visibly. See Factor IV: Backing services examples in TypeScript, Python, and Go.

Factor V: Build, release, run

Original claim: Factor V separates build, release, and run. Build converts source into an executable artifact. Release combines that artifact with deploy configuration. Run starts processes from the selected release.

Failure mode: Startup installs dependencies, compiles source, or applies unversioned patches. Two starts of the same nominal release can produce different bytes. Promotion rebuilds from source, and rollback cannot recover the artifact that previously ran.

Modern reading: Build once, identify the artifact by an immutable digest, attach provenance and source revision, then promote those bytes. A release adds deploy configuration and its own identifier without mutating the artifact. Database migrations are explicit admin work, not a hidden side effect of every process start.

Verify it: Promote one artifact digest through two environments with different release configuration. Block network access to source and package registries at runtime. Roll back by selecting the prior release without invoking a build. See Factor V: Build, release, run examples in TypeScript, Python, and Go.

Factor VI: Processes

Original claim: Factor VI runs the application as stateless, share-nothing processes. Durable state belongs in a backing service that outlives any one process.

Failure mode: Sessions live in web-process memory, uploads live on an instance filesystem, or worker retries rely on an in-memory completed set. Routing a request elsewhere loses state. Restarting an instance erases accepted work or repeats a business effect.

Modern reading: Process memory remains useful for bounded caches and active work, but correctness cannot depend on it surviving. PostgreSQL, object storage, and queues hold durable state. Idempotency keys and database constraints protect effects that may be retried after an ambiguous failure.

Verify it: Accept an order, terminate that instance, and read the order through another instance. Deliver the same job twice and observe one durable effect. See Factor VI: Processes examples in TypeScript, Python, and Go.

Factor VII: Port binding

Original claim: Factor VII exports an HTTP service by binding to a port. The application includes the server it needs instead of relying on a web server injected into the runtime environment.

Failure mode: The service depends on an undeclared host server, assumes one fixed port, or confuses its internal listener with its public URL. The same artifact cannot run twice on one host or move cleanly between a laptop, container, and scheduler.

Modern reading: A network process owns a self-contained listener and binds an injected address and port. The platform supplies discovery, public routing, and any edge proxy. Workers, scheduled jobs, message consumers, and function handlers have non-HTTP invocation contracts, so they do not open a port merely to satisfy the factor.

Verify it: Start two instances of the same artifact on different ports and route traffic to both. No framework-specific server should be installed on the host. Confirm that web, worker, and admin process types each expose the invocation contract their workload needs. See Factor VII: Port binding examples in TypeScript, Python, and Go.

Factor VIII: Concurrency

Original claim: Factor VIII scales an application through the process model. Named process types represent different workloads, and the platform changes the number of processes for each type.

Failure mode: One opaque process handles HTTP, scheduled work, and queue consumption. A traffic spike scales unrelated work, while an unbounded worker accepts more jobs than its database, memory, or downstream APIs can sustain.

Modern reading: Scale the web and worker fleets independently, then bound concurrency inside each process. Queue depth, processing latency, and resource saturation inform worker replica count. Backpressure protects backing services because horizontal scaling can multiply database connections and outbound requests faster than it improves throughput.

Verify it: Increase worker replicas without changing the web fleet. Confirm the queue drains faster, each worker respects its concurrency limit, and total work stays within database and downstream capacity. See Factor VIII: Concurrency examples in TypeScript, Python, and Go.

Factor IX: Disposability

Original claim: Factor IX makes processes easy to start and stop. Startup is fast, termination is graceful, and sudden death does not corrupt the system.

Failure mode: A process advertises readiness before its dependencies work, continues accepting requests after termination begins, or abandons a job after producing an external effect but before acknowledging it. Slow startup delays recovery, while unsafe retry duplicates business actions.

Modern reading: Startup, readiness, liveness, and shutdown are separate contracts. A terminating instance removes readiness, stops new work, drains within a deadline, closes resources, and exits before the platform’s grace period. Idempotency and retry safety remain necessary because hard kills bypass graceful shutdown.

Verify it: Measure time to readiness. Send termination during an HTTP request and a queued job, then confirm readiness fails first, accepted work finishes or is retried safely, and the process exits within its deadline. Force-kill a worker to test the path that signal handlers cannot protect. See Factor IX: Disposability examples in TypeScript, Python, and Go.

Factor X: Dev/prod parity

Original claim: Factor X narrows three gaps: the time between writing and deploying code, the people who write and deploy it, and the tools or backing services used in each environment.

Failure mode: A change waits weeks for release, passes from developers to a separate operations group without shared ownership, or runs against a substitute whose transaction and query behavior differ from production. The first faithful test happens after deployment.

Modern reading: Parity means production-significant contracts match, not that every environment is identical. Unit tests cover pure behavior. Disposable integration environments exercise the real database and queue types. Staging or controlled production checks cover identity, topology, scale, network policy, and failure modes that a laptop cannot reproduce honestly.

Verify it: Inventory every deliberate difference across local, CI, staging, and production. Name the behavior it can change, the test layer that covers it, and the owner of that evidence. Track how quickly a merged change reaches production and whether its authors can observe the result. See Factor X: Dev/prod parity examples in TypeScript, Python, and Go.

Factor XI: Logs

Original claim: Factor XI treats logs as event streams. The application writes each event without managing log files, routing, retention, or final storage.

Failure mode: A process writes rotating files to its local filesystem, sends directly to one vendor, or emits plain text without service and release identity. Operators enter a dying instance to reconstruct a request and lose the evidence when that instance disappears.

Modern reading: Standard output and standard error remain the collection boundary for containers. Structured events carry timestamp, severity, service, release, request, and trace fields. Metrics and traces answer questions that logs cannot, while the platform owns collection, sampling, routing, retention, and access policy. Sensitive values are redacted before emission.

Verify it: Submit one failing request and reconstruct its path from the external event stream using release, request, and trace identifiers. Repeat with a synthetic sensitive marker and confirm it never reaches collected output. See Factor XI: Logs examples in TypeScript, Python, and Go.

Factor XII: Admin processes

Original claim: Factor XII runs one-off administration from the same codebase, configuration, dependency graph, and release as the application’s long-running processes.

Failure mode: An operator runs a migration from a stale checkout with local tools and broad credentials. The command has no bound, no release identity, and no durable record connecting its actor, target, and result.

Modern reading: Package narrow admin commands in the normal artifact and run them as bounded jobs. Give each invocation short-lived identity, least privilege, a timeout, resource limits, concurrency policy, and audit evidence. Restartable migrations are safer than an unrestricted production shell or interactive REPL.

Verify it: Run the migration from the production artifact in a non-production environment, interrupt it, and retry it. Record the actor or workload identity, exact command, release digest, target, start and end times, and result. Confirm the admin identity cannot perform unrelated runtime actions. See Factor XII: Admin processes examples in TypeScript, Python, and Go.

Audit the factors by breaking assumptions

A document review can show intent, but it cannot prove runtime behavior. Start with one observable question for each factor, then inject the smallest safe failure that could disprove the claim.

FactorObservable audit questionFailure exercise
Factor I: CodebaseCan each web, worker, and admin process report the same release and source revision?Deploy an artifact with mismatched revision metadata and require the release gate to reject it.
Factor II: DependenciesCan a clean environment install, test, and start from only committed manifests and locks?Empty the dependency cache and block undeclared global tools during the build.
Factor III: ConfigDoes invalid configuration fail before readiness without exposing its value?Remove DATABASE_URL, corrupt PORT, and place a synthetic sensitive marker in a rejected value.
Factor IV: Backing servicesCan an attachment move to a fresh compatible endpoint without a source edit?Replace PostgreSQL or Redis with an unavailable endpoint, then a fresh valid instance, and inspect both paths.
Factor V: Build, release, runDoes promotion and rollback select existing artifact bytes without rebuilding?Block package registries at runtime and attempt rollback by digest after the source branch changes.
Factor VI: ProcessesDoes accepted state survive instance loss and repeated delivery?Terminate the accepting web process, restart elsewhere, and deliver the same order job twice.
Factor VII: Port bindingCan the same artifact bind a supplied address and port without a host-installed server?Start two copies on different ports, then occupy one port and require a visible startup failure.
Factor VIII: ConcurrencyCan web and worker capacity change independently while work remains bounded?Increase worker replicas and queue depth while holding the per-worker limit and database budget fixed.
Factor IX: DisposabilityDoes readiness drop before intake stops, and does shutdown meet its deadline?Send termination during active HTTP and worker work, then repeat with a hard kill.
Factor X: Dev/prod parityIs every production-significant difference owned by a faithful test layer?Swap a local fake for the production database type and run the same contract suite.
Factor XI: LogsCan an operator reconstruct one failure from external events without entering the instance?Trigger a traced failure, terminate the process, and search collected output by release, request, and trace identifiers.
Factor XII: Admin processesCan each one-off action be tied to its actor, release, target, duration, and result?Run an unsupported migration target and require bounded failure with no unrestricted shell or broad authority.

Record the starting state, injected fault, expected observation, actual observation, and cleanup result. A passing agent explanation is not evidence. The test output, artifact identity, event stream, database state, and process exit behavior are the evidence.

Repository-level AI harnesses

Each reference repository separates guidance from enforcement. The root instructions give every task the application contract. The skills provide a focused Twelve-Factor review workflow for Codex and Claude. The repository-owned check remains the authority because it runs without either agent.

Codex reads repository AGENTS.md instructions before work and can load repository skills from .agents/skills. The official AGENTS.md guide and official skills guide describe those discovery rules. A SKILL.md can guide factor analysis, focused checks, and reporting, but executable tests must decide whether a contract passed.

Claude Code reads project instructions from CLAUDE.md and project skills from .claude/skills. Anthropic’s official project-memory guide recommends importing an existing AGENTS.md from CLAUDE.md when both tools share a contract. Its official skills guide documents project skill discovery and description-based activation. These files guide behavior; repository checks enforce the result.

TypeScript harness at v1.0.2

Root AGENTS.md, root CLAUDE.md, Codex skill, Claude skill, factor checklist, and check-twelve-factor.mjs.

Python harness at v1.0.2

Root AGENTS.md, root CLAUDE.md, Codex skill, Claude skill, factor checklist, and check_twelve_factor.py.

Go harness at v1.0.3

Root AGENTS.md, root CLAUDE.md, Codex skill, Claude skill, factor checklist, and check-twelve-factor.sh.

Use the same evaluation shape for either agent: ask for an explicit factor review, make a related change without naming the skill, ask for an unrelated change that should not invoke it, introduce a deliberate violation, and make the deterministic check fail. Record which instructions were loaded, which factors were named, which commands ran, and whether the agent surfaced the failing evidence.

Where literal compliance misleads

The original wording describes useful application properties through mechanisms common to its era. Preserve the property when a newer mechanism provides stronger evidence. Do not stretch the wording into a rule the methodology never needed.

Literal readingDurable principleBetter evidence
One codebase forbids monoreposA deployable application has one traceable source historyA release resolves to an exact revision and build target
Every configuration value must be an environment variableDeploy-varying configuration stays outside the artifactValidated environment values, mounted files, external stores, or workload identity can configure one unchanged artifact
Two attached services are interchangeable when their URLs have the same shapeProviders attach through explicit boundariesContract tests expose differences in transactions, consistency, delivery, limits, and failures
Stateless processes mean a stateless systemReplaceable processes do not own durable stateAn instance can disappear while required state survives in a backing service
Every workload must bind a portEach process exposes a narrow invocation contractServers bind listeners, while workers and jobs accept messages or commands
Dev and production must reproduce the same topologyProduction-significant contracts need faithful testsEvery deliberate difference has a named risk, test layer, and owner
Writing text to stdout completes observabilityThe application emits externally collectable signalsCorrelated logs, metrics, and traces reconstruct an outcome without entering an instance
Admin processes justify an unrestricted production shellOne-off work uses the release’s code and configurationBounded commands run with short-lived authority and durable audit evidence

This interpretation does not weaken Twelve-Factor. It makes each claim testable against the application-platform contract instead of a preferred tool.

Official modernization status

Status checked September 8, 2026: The official repository uses next as its default development branch. Its README says this work is intended to replace the hosted text when maintainers agree it is complete. 12factor.net still presents the original twelve factors. The work below is proposed, not adopted canon.

The modernization effort keeps the narrow application-platform interface at its center. Its vision separates factors, concrete examples, and broader guidance so a durable requirement does not become tied to one platform mechanism.

Official workState on September 8, 2026Direction under discussion
Issue 3: LogsOpenReplace a stdout-only reading with standards-based telemetry and correlation
Issue 4: ConfigOpenPermit mounted and externally supplied configuration or secrets while preserving separation from code
Issue 9: IdentityOpenMake short-lived workload identity part of the application-platform contract
Pull request 32: ProcessesOpenCombine related process guidance, including one-off administration
Pull request 34: IdentityOpenMove admin guidance into Processes and use Factor XII for workload identity
Pull request 40: FacetsOpenGroup factors by the operating properties they enable
Pull request 33: Dynamic configClosed without mergeProposed a reference from an environment value to an external dynamic-config source

The Identity proposal is the largest structural change. It depends on the process consolidation in pull request 32, then proposes short-lived credentials supplied at runtime and scoped to an audience or backing service. That model separates workload identity from static application configuration. Until the pull request merges and the hosted method changes, it remains a design proposal.

The facets proposal is a reading aid, not four new factors. It asks what operating property a group of factors makes possible:

Continuously Deployable
codebase + dependencies + config + build/release/run
+ disposability + dev/prod parity
Configurable
config + backing services + build/release/run + parity
Scalable
backing services + processes + port binding
+ concurrency + disposability
Observable
process and service boundaries + telemetry

A team could use these facets to find a weak property across several factors. It should not report them as a replacement list while pull request 40 remains open.

Independent extension models

There is no single accepted “extended Twelve-Factor App.” Later authors reorder the original factors, add production concerns, or move the discussion from an application to a whole service platform. Compare them by the gap they address instead of combining them into an invented canon.

Hoffman’s reordered 15-factor model

Kevin Hoffman’s 2016 book, Beyond the Twelve-Factor App, revises and reorders the model for cloud-native applications. Calling it the original twelve plus three hides those changes. Its sequence is:

  1. One Codebase, One Application
  2. API First
  3. Dependency Management
  4. Design, Build, Release, Run
  5. Configuration, Credentials, and Code
  6. Logs
  7. Disposability
  8. Backing Services
  9. Environment Parity
  10. Administrative Processes
  11. Port Binding
  12. Stateless Processes
  13. Concurrency
  14. Telemetry
  15. Authentication and Authorization

API First makes the service contract a design input. Telemetry expands operational evidence beyond log streams. Authentication and Authorization makes trust explicit. The reordered sequence also places design in the release lifecycle and credentials beside configuration, so use Hoffman’s framework as an independent revision rather than an official amendment.

IBM’s seven missing factors

IBM engineer Shikha Srivastava’s 2019 proposal, 7 Missing Factors from 12-Factor Applications, adds factors XIII through XIX for containerized microservices on Kubernetes and enterprise platforms.

NumberFactorProduction concern
XIIIObservableOperational visibility beyond emitted log streams
XIVSchedulableResource and placement requirements the platform can act on
XVUpgradableSafe evolution of code, dependencies, interfaces, and persistent data
XVILeast privilegeMinimum authority for users, workloads, and components
XVIIAuditableDurable evidence of operational and security-relevant actions
XVIIISecurableProtection across development, delivery, and runtime boundaries
XIXMeasurableAttributable resource use, cost, and delivered value

This is best read as an enterprise production-readiness extension. It reaches beyond application packaging into scheduling, governance, cost, and platform operations. Its categories also overlap: least privilege and auditability support security, while measurement and observability can share instruments without answering the same questions.

A CNCF-hosted 2022 reassessment

The CNCF-hosted guest post Twelve-factor app anno 2022 distinguishes application-level properties from service-level properties. Source layout and dependency declarations largely belong to the built application. Scheduling, routing, rollout, and some configuration behavior emerge from the application plus deployment definitions and platform controllers.

That distinction prevents a common review error: crediting application code for a platform control, or blaming code for a missing platform contract. The post also identifies security and automated testing as clear omissions. Security should influence every relevant boundary, while tests need to cover units, components, integrations, and end-to-end behavior at the appropriate application or service layer. This is a guest reassessment hosted by CNCF, not official CNCF policy or a replacement standard.

NGINX amendments as historical prior art

The official modernization repository lists NGINX’s microservices amendments as prior art. The original article is no longer available at its former location. The repository preserves an archived 58-page microservices reference architecture deck that discusses API routing, service discovery, load balancing, security, resilience, and health checks.

Those ideas helped move the conversation toward service-level architecture, but the surviving source does not justify reconstructing a definitive numbered NGINX factor list. Treat it as historical influence with a limited primary record.

Where the extensions overlap

The useful result is not a longer checklist. It is a map from a missing concern to the canonical boundary it strengthens and the separate framework it may require.

Modern concernProposal familiesNearest canonical homePractical treatment
API contractsHoffman, NGINXBacking services, port bindingDesign interfaces first and test compatibility across versions and providers
Telemetry and observabilityHoffman, IBM, CNCF, issue 3, facets proposalLogsKeep event streams, then add correlated metrics, traces, profiles, and operating outcomes
Workload identity and authorizationHoffman, IBM, issue 9, pull request 34Config, backing servicesSupply short-lived identity at runtime and authorize each intended audience
Scheduling and resource contractsIBMConcurrency, disposabilityDeclare resources, placement, bounded work, backpressure, and termination behavior
Safe upgradesIBMBuild/release/run, admin processesTest interface and schema compatibility, progressive rollout, migration, and rollback
Audit evidenceIBMLogs, admin processesRecord who or what acted, against which release and target, under which authority
Security and least privilegeIBM, CNCF, HoffmanEvery factorApply threat-driven controls throughout and use a complete secure-development framework
Measurement and cost attributionIBMConcurrency, telemetryConnect resource consumption to service outcomes without equating activity with value
Automated testingCNCFDependencies, parity, release lifecycleProve contracts and failure behavior at the cheapest faithful layer

What the factors still do not settle

Twelve-Factor gives an application a clean operational boundary. It does not provide a complete production, security, reliability, or data-management system. A review should name these gaps rather than award a compliance score that hides them.

Missing concernQuestions Twelve-Factor does not answerComplementary direction
Identity and authorizationWhich user or workload may call which resource, with what scope, lifetime, and revocation path?Workload identity, service authorization, least privilege, and policy tests
Secure developmentHow are threats identified, vulnerabilities handled, secrets scanned, and security requirements verified?NIST Secure Software Development Framework
Software supply chainWho built the artifact, from which inputs, and what proves it reached deployment unchanged?SBOMs, trusted builders, attestations, verification policy, and SLSA provenance
Health and resourcesWhen is a process ready, when should it restart, and how much CPU, memory, storage, or downstream capacity may it consume?Startup, readiness, liveness, drain, resource, quota, and backpressure contracts
Data lifecycleHow do schemas evolve, backups restore, records expire, residency rules hold, and regions recover?Migration compatibility, restore tests, retention policy, consistency decisions, and recovery exercises
Network securityWhere is transport authenticated, which egress is allowed, and how are abusive or unexpected calls contained?TLS boundaries, segmentation, service policy, rate limits, and denial-of-service controls
ReliabilityWhat availability and latency are promised, how much failure is acceptable, and when should the system shed load?Service-level objectives, error budgets, capacity tests, load shedding, and regional recovery
Delivery governanceWho may promote or roll back, which evidence gates a release, and how are risky changes introduced safely?Policy checks, separation of duties, progressive delivery, compatibility gates, and audited rollback

OpenTelemetry, SLSA, NIST SSDF, and platform-specific contracts complement Twelve-Factor because they answer different questions. They do not need to be renamed as more factors to belong in the same engineering review.

References

  • Docker, the artifact and process boundary used by the reference services
  • Kubernetes, one platform that can schedule, route, configure, and stop those processes
  • GitOps, reconciliation and release promotion after the application contract is defined
  • Secrets, keys, and tokens, credential types and secure delivery into deploy configuration
  • Scalability, capacity, bottleneck, partitioning, and replication models beyond process concurrency