Capability¶
The authority to obtain a credential at final use. Brama holds no secret at rest: a capability is a short-lived, single-use handle the local Skarbiec broker issues and redeems, and the plaintext it yields exists only for the one provider call it pays for. Skarbiec owns the secrets and the redemption verdict; Brama owns only the seam.
Shape¶
A capability binds three things (src/gateway/broker.rs):
- a purpose —
brama.provider.authenticatefor provider credentials,brama.request.signfor agent request-sign secrets; - a resource — the vault coordinate the operator's routes table names:
provider:<slugged-provider>for a direct credential,provider:<provider>:<subscription>for a subscription credential,agent:<slugged-agent>for a signing secret. Identifiers are slugged into a stable resource alphabet; the original identifier remains the lookup key in trusted config; - an agent — capabilities are issued to
brama-runtime, the acquisition consumer bound to the workload proof key this installation provisions (deliberately notbrama-service, which holds only areadcapability and can never redeem).
Each request-path issue states one permitted redemption and a lifetime from
BRAMA_CAPABILITY_LIFETIME_SECONDS. The managed launcher validates
services.brama.capability_lifetime_seconds in its control document
as a positive whole number and exports it to the gateway; a direct gateway
must receive the variable explicitly. Missing, malformed or zero lifetime
refuses the managed launch or the direct capability issue before Skarbiec is
asked. Skarbiec supplies neither a default nor a ceiling for either value.
Nothing is cached: the request redeems its capability once, and an id placed
in a process environment could not be refreshed for a later request.
Lifecycle¶
- The launcher builds trusted subscription metadata and starts the owner-bound broker without pre-issuing capabilities. A boot-time id is single-use, cannot be refreshed through a process environment, and model discovery may spend it before the first request.
- On the request path, immediately before the provider HTTP call, the gateway obtains a fresh capability for the purpose and resource and redeems it through the owner-bound broker socket.
- Where issuance or redemption is refused, the gateway asks the authority
once more for the exact field-scoped read grant the vault may carry
for that coordinate (
read:provider:local-openai#tokenis exactly that shape), and a refusal there is the answer. Nothing is widened: the router presents this host's consumer identity and the authority still decides. - The returned secret is used once and dropped; plaintext never outlives the call.
Startup, alias resolution, and /readyz all ask the same question the
request path asks: is there a capability or a read grant for this provider.
Standalone mode¶
In standalone desktop deployments there is no broker: the launcher passes a
provider-to-credential JSON object ({"openai": "sk-...", ...}) once over
brama serve --local-credentials-stdin. The input is consumed and zeroized;
plaintext then remains only in zeroizing process memory for that server
lifetime. /readyz in this mode reports a provider credential: true from
the in-memory map without contacting the provider.
Invariants¶
- Two pools, no substitution. Holding a direct capability for a provider does not let a caller spend an agent's subscription on that provider, and owning a subscription does not unlock the deployment's direct credential. Neither pool is ever charged in the other's place, and the refusal says which pool was asked.
- Final-use only.
/statsreports the dependency policy as"capabilityBroker": "final-use": no timer, listing, or catalog read redeems a capability; only a request that is about to spend does, plus the explicit/readyzprobe. - Coordinates are named in failures. The dispatch path names the vault coordinate in provider failures, because the repair to a credential that cannot be used is always at the coordinate it came from.
Refusals¶
- A direct route whose provider has no capability, read grant, or in-memory
credential:
direct '<provider>' credential is unavailable— surfaced as503dependency_unavailableat the HTTP edge (observed against 0.2.38). - When the authority answers a refusal, the capability attempt is
credential_unauthorized, not a rate limit; waiting does not repair its authorization (errors). - A failed connection, write or read of the authority socket is
InfraDownatbrama.gateway.credential-redeem, with the socket operation and operating-system cause. An unreadable workload proof key names its file operation and cause asInfraDown; a malformed or unsafe key declaration remainsConfig. These are not authority denials. - If the field-scoped read grant also refuses, its failure is the final answer and the earlier capability failure remains in its cause chain. A working read grant may still serve the request.
Client configuration diagnostics
The capability client names the missing or invalid SKARBIEC_CAP_SOCKET, SKARBIEC_WORKLOAD_ID or SKARBIEC_WORKLOAD_SIGNING_KEY_FILE declaration. Socket and declared signing-key paths must be absolute. Key-file refusals distinguish opening, metadata inspection, regular-file type, effective-user ownership, group/other permissions, length, reading and seed decoding. Diagnostics contain the path and observed metadata, never the key bytes. The accepted Ed25519 seed formats and owner-only checks are unchanged. An entropy-read failure names the proof nonce operation and its operating-system cause.
Qualify the real client API with cargo test --test workload-authority -- --ignored --exact capability_configuration::capability_configuration_preserves_actual_refusal_or_redeems_expected_secret. Supply TEST_SOURCE_REVISION and the actual client environment. For EXPECTED_CAPABILITY_OUTCOME=configuration-refusal, supply EXPECTED_CAPABILITY_RESOURCE and EXPECTED_CAPABILITY_CAUSE from an isolated existing invalid fixture. For EXPECTED_CAPABILITY_OUTCOME=redeemed, supply a disposable real CAPABILITY_ID, its CAPABILITY_RESOURCE and the independently known EXPECTED_SECRET_SHA256; this branch consumes the authority-issued capability and verifies the actual returned credential, without submitting inference. Evidence is retained under target/real-tests/capability-configuration, without plaintext keys or returned credentials. This API qualification does not establish CLI or native-screen diagnostic delivery.
The redeemed branch also requires boolean EXPECTED_SECRET_UTF8. Use a real isolated credential whose independently verified bytes are valid text for success, or invalid UTF-8 for refusal; the latter additionally requires EXPECTED_DECODE_CAUSE. Decoding failure is SecretEncoding, not an authorization denial: the capability was already redeemed. The decoder reports its actual byte-position/encoding cause without printing the secret. Plan-tier, plan-usage and refresh diagnostics preserve that cause with the credential resource; a failed refresh decoding step retains the earlier provider rejection as well.
Broker declaration parsing distinguishes an absent optional map from malformed JSON or a non-Unicode environment value, naming the declaration and parser or environment cause. Invalid configured provider bindings are reported instead of omitted. Metadata inspection does not construct a capability client or read the workload signing key; final-use redemption preserves the actual client-construction refusal. Request-sign lookups retain the agent/resource, binding, client, issuance and redemption causes through their consumer. Strict central identities never substitute another identity. On subscription admission the unauthenticated response remains the deliberately generic 401 unauthorized; the operator's caller_auth_rejected log retains the actual reason.
Qualify request-sign lookup through its real broker API with cargo test --test workload-authority -- --ignored --exact capability_configuration::request_sign_lookup_preserves_actual_refusal_or_expected_identity. Supply TEST_SOURCE_REVISION, REQUEST_SIGN_AGENT, the actual isolated identity/authority configuration and boolean EXPECTED_SIGNING_SUCCESS. A successful lookup must equal the independently supplied EXPECTED_SECRET_SHA256; a refusal must preserve EXPECTED_SIGNING_RESOURCE and EXPECTED_SIGNING_CAUSE. The real capability path can issue and consume a capability; use a disposable isolated identity, not an operator credential. The journey submits no inference and retains non-plaintext evidence under target/real-tests/request-sign-lookup. CLI admission logs and native diagnostics require their own actual-surface qualification.
Capability wire failures are not authorization denials. Control-line reads preserve the socket and operating-system cause; premature EOF includes the observed control-line byte count. A failed read after the secret names the secret-boundary operation, while trailing bytes are an invalid authority response. No secret bytes are included in these diagnostics. Qualify an actual isolated failure with cargo test --test workload-authority -- --ignored --exact capability_configuration::capability_redemption_retains_actual_wire_failure, supplying TEST_SOURCE_REVISION, a disposable real CAPABILITY_ID, CAPABILITY_RESOURCE, actual client environment, EXPECTED_CAPABILITY_OPERATION and independently observed EXPECTED_CAPABILITY_CAUSE. The test requires a real authority/transport fault, creates no simulated server, and retains evidence under target/real-tests/capability-wire. A request may consume the capability even if its response cannot be read; use only an isolated fixture.
Not to be confused with¶
- A provider. A provider is the protocol adapter; the capability is the permission to spend through it.
- A subscription credential. Same redemption seam, different pool and different owner — see subscription and entitlement.