[ AxiomCore · Documentation ]
Secrets at runtime
How protected backend runtimes, server extensions and frontends consume write-only project secrets through purpose-bound handles.
Keep credentials out of source and artifacts while actions and server extensions still use them. A project stores write-only secret versions per environment; a protected runtime receives a purpose-bound handle, never the raw value.
For step-by-step tasks, use Secrets in the Cloud section and the secrets commands (source preview).
Diagram source
flowchart LR
A[Secret definition and purpose] --> B[Candidate version]
B --> C[Owner activates version]
C --> D[Binding to a declared requirement]
D --> E[Expiring grant to a workload]
E --> F[Runtime handle]
F --> G[Approved adapter uses credential]Add a Cloud secret
- Open your project in the Cloud Dashboard and choose Secrets.
- Create a logical environment and a secret definition with its intended purpose. Select both before entering a value.
- Save the value. Saving clears the input and creates a candidate version. Saved values have no reveal or download action.
- An owner activates the candidate against the current configuration revision.
- A binding maps a declared requirement to an environment secret and a reviewed consumer. A separate expiring grant authorizes a developer or workload to use that binding.
Creating a definition, writing a value or owning a project grants no consumption. Production environments are protected: developer grants apply only to unprotected development and staging environments, and a production workload uses its own registered identity. New environments inherit no values or grants. When a preview environment expires, access closes and versions and audit history are kept.
Choose the runtime source explicitly
The protected preview reads a reference-only AxiomSecrets.toml that selects
one source for each logical requirement. There is no automatic dotenv
discovery in parent directories, no source precedence, interpolation or shell
execution, and no fallback from Cloud to local values.
format = "axiom-secret-bindings/v1"
[environments.development.secrets.paymentsCredential]
source = "dotenv"
file = ".env.local"
key = "PAYMENTS_API_KEY"- The value file must belong to the runtime user and be readable only by that user. Relative paths stay inside the project root. Symlinks and files with several hard links are rejected. Compilation never reads the value file. Keep it out of version control and public assets.
- Cloud bindings also pin the exact project, logical environment, binding identity and immutable numeric version.
- Changing the source never requires putting a credential in code.
Declare the requirement and its consumer in backend Acore. This partial snippet declares HTTP authentication; it contains and loads no value:
secret payment(purpose: SecretPurpose.authenticateHttp)
resource payments(lifetime: ProviderLifetime.application, secrets: [Secrets.payment]) {
operation call(input: Void, output: String, effect: EffectKind.read)
}The source preview's purposes are signRequest, authenticateHttp,
verifyToken, connectDatabase and authenticateWorker. The reviewed
deployment's adapter refers to secret:payment; keep the provider origin and
other non-secret settings as separate config: references. Bind the exact
compiled consumer and plan to its allowed destination; a declaration alone is
not an access grant. The preview command axiom secrets requirements lists
declared resource requirements.
Integrations that read process environment variables keep their
documented provider workflow. They do not gain the
protected preview's guarantees by using a .env filename. External Python and
Go application processes need an explicitly qualified integration.
Keep consumption inside the owning boundary
| Consumer | What it receives | What uses the credential |
|---|---|---|
| Backend action | A purpose-bound runtime capability | An approved native adapter |
| Server WASM extension | An opaque, invocation-scoped handle | The host broker and approved adapter |
| Frontend contract or extension | An authorized business operation result | The application backend |
| Browser configuration | Selected public, typed fields | A separate public configuration projection |
Purposes cover HTTP authentication, request signing, token verification, database authentication and internal worker authentication. A handle cannot be turned into a string, logged as material or returned in a business model. An HTTP grant also restricts the consumer, origin, method and path; redirects and ambient proxies cannot change the approved destination.
Server extensions
An extension needs explicit injection for its reviewed package, module, authority, export and purpose; a package declaration alone grants nothing. Rust, TypeScript and Python server guests share the same opaque-handle boundary. Frontend extensions cannot obtain shared project secrets. This partial profile shows the required pins; replace the placeholders with reviewed metadata:
[environments.development.sandboxes.paymentsGuest]
plan_sha256 = "EXACT_BACKEND_PLAN_SHA256"
module_sha256 = "EXACT_WASM_MODULE_SHA256"
authority_sha256 = "EXACT_REVIEWED_AUTHORITY_SHA256"
export = "call"
[environments.development.sandboxes.paymentsGuest.secrets.payment]
binding = "payment"
origin = "https://api.payment-provider.example"
method = "POST"
path_prefix = "/payments"The payment binding refers to the selected profile's secret source. The
package's reviewed permissions must also allow the purpose and the network
operation. A Cloud sandbox binding also pins the canonical package
fingerprint. Missing or mismatched injection is denied before use. With the
matching TypeScript SDK 0.1.3, a server guest requests the handle with
context.secret("payment") and passes it to
context.authenticated_request(...). These are server SDK calls, not a
browser secret API; the native broker performs the credential operation.
Frontends
A frontend calls a named backend operation, such as creating a checkout session. The backend still enforces authentication, user and tenant authorization, CSRF where applicable, quotas, and typed input and output. Do not expose a generic URL relay or signing operation. Server-rendered pages keep credential use on the server and hydrate only public configuration and approved results.
The source web frontend path has mounted qualification. iOS and Android compile checks do not establish mounted runtime support. Containers, Workers, other native operating systems and older readers fail closed for protected capabilities and have separate qualification gates.
Rotate and revoke
- Save a new candidate and activate it.
- Update the reviewed version pin. Activation does not silently rewrite a running generation or an explicit pin.
- Protected local watch prepares a replacement before switching new requests. A failed preparation keeps the previous generation, subject to its expiry and revocation rules.
To stop further use, disable a compromised version or revoke its grant. Cloud leases last at most five minutes. Each material use requires a central audit acknowledgement, so a Cloud or audit outage can deny use before a lease expires. Retire the credential at its upstream provider separately: revoking an Axiom handle does not revoke the upstream credential.
Audit history records identities, versions, consumers, operations and outcomes, never values. A permitted event authorizes material use; it does not prove an upstream business transaction completed. When audit capacity is exhausted, new use is denied and evidence is kept.
Trust boundary
The boundary includes the trusted runtime, adapters, operating system, encryption service and approved credential destination. It does not protect against a compromised privileged host or every transformation by a malicious upstream. Managed-source isolation cannot detect credentials pasted directly into source code.
Next steps
Integrations and transports
Declare server caching, request batching, transactional batch writes, outbound HTTP, multipart uploads, SSE, WebSockets and server telemetry.
Deployment targets
Choose and package an Acore backend for the native server, Linux containers, local Cloudflare Workers or a FastAPI or Go Chi framework adapter, with each target's status and limits.