Secrets in code
A secret is a value the host writes into a service's outgoing requests. The service names it as {secret:NAME} and never reads it; a person sets it.
A service names a secret in a request it sends, and the host writes the value in on the way out. The service never holds the value, and neither does anything that reads its code, its logs or its calls.
Declaring them
A service declares its fixed credentials in its crab.toml: grouped as a credential, with its destinations and a guide to getting it from its provider. Bare secrets = ["NAME"] declarations have no outbound destinations and cannot be injected into HTTP requests.
[credentials.example]
title = "Example API key"
hosts = ["api.example.com"]
secrets = [{ name = "EXAMPLE_KEY" }]
[http]
fetch = ["api.example.com"]A service linking a library also inherits its declared secrets and credentials.
Using them
{secret:NAME} in a header value or in the body of a request is replaced by the value as the request leaves:
let page = berm_lang::http::fetch(
"GET",
"https://api.example.com/items",
&[("Authorization", "Bearer {secret:EXAMPLE_KEY}")],
b"",
)?;- It works the same in
http::fetch,http::fetch_allandhttp::proxy. - A request goes only to hosts allowed by
[http] fetchor[http] proxy. Secret injection additionally requires the destination in the credential's manifesthostsand in the destinations saved when its value was provisioned. - A request naming a secret the service does not declare, one that is not set, or one not set for the request's host, is refused before anything is sent. A header naming an unset secret of an optional credential is left off instead.
- A failed call's tape records each request before its secrets are written in, so no value is on it.
- In a unit test,
test::fetchedlists the requests with{secret:NAME}as written. OnTestHost,grantsets one for a host.
Setting them, and the rules a secret is held to: Secrets.
Runtime secret resources
Secrets added while a service is running are account-owned resources with opaque IDs. Enable their use separately from fixed credential declarations:
secret_resources = true
[http]
fetch = ["api.example.com"]An owner provisions a resource and grants the deployed service access at exact destination hosts. Store the returned secret ID in application data. In a request header or body, {secret:ID} asks the host to substitute its value. The grant and the service's HTTP permissions must both allow the destination. Missing grants refuse dispatch; values never enter guest memory.
Resources can be created, rotated and revoked after deployment. Individual IDs are not declared in the manifest. See runtime provisioning.
berm_lang::secret::owner(id, host) returns ownership metadata only when this deployment has a grant for that destination. It never returns a value. Use http::fetch_all_literal_body for user-supplied body bytes: secret placeholders are interpreted only in headers.