Skip to main content
nono integrates with the SPIFFE Workload API to authenticate outbound API calls using workload identity. Instead of storing a secret in a keystore or profile, nono contacts the local SPIRE agent socket at startup, obtains a credential, and handles injection automatically. The sandboxed process makes a plain HTTP request and is never aware a credential was used. JWT-SVIDs are currently supported. nono fetches a short-lived token per request and injects it as a bearer header; refresh is handled by the SPIRE agent cache. Most of the operational work lives on the SPIRE side: running the server and agent, writing attestation policies, and registering workload entries. nono’s profile config is just a socket path and what to request.

Profile configuration

There are two separate configuration surfaces depending on what the upstream expects:
  • spiffe block — for upstreams that accept a JWT-SVID directly as a bearer token.
  • auth.client_assertion — for OAuth2 token endpoints that accept a JWT-SVID as a urn:ietf:params:oauth:grant-type:jwt-bearer assertion and return a short-lived OAuth2 access token in exchange.

JWT-SVID (direct bearer injection)

Add a spiffe block to any custom credential route. It is mutually exclusive with credential_key, auth, and aws_auth.
nono injects the token as Authorization: Bearer <jwt>. Change inject_header to target a different header, or set credential_format to change the value format ({} is replaced by the token).

JWT-SVID as an OAuth2 client assertion

Some upstreams (including Anthropic’s API) accept a JWT-SVID as an OAuth2 client assertion via the urn:ietf:params:oauth:grant-type:jwt-bearer grant type. The upstream issues a short-lived OAuth2 access token in exchange. nono handles the full exchange and injects the resulting access token — not the raw JWT-SVID — into upstream requests. Use auth.client_assertion instead of the spiffe block for this flow:
When client_assertion is set, client_id and client_secret are not required — the JWT-SVID is the credential. Any extra parameters required by the token endpoint (such as federation rule IDs or workspace identifiers) can be passed via auth.extra_params:
The difference between this and the spiffe.type: jwt block is the intermediary step: here nono exchanges the JWT-SVID for an OAuth2 token and caches it until near expiry; with spiffe.type: jwt the raw JWT-SVID is injected directly with no exchange.

Options reference

spiffe block

svid_hint is useful when the SPIRE agent issues more than one SVID for the same workload — for example, one for an internal service mesh and one for an external API. Set it to the SPIFFE ID of the SVID you want nono to use; if absent, nono uses the first SVID returned by the agent.

auth.client_assertion block


Socket path by platform

The SPIRE agent socket path varies by platform and installation: Set workload_api_socket to match wherever your agent is listening. nono fails at startup if the socket is unreachable, so misconfigured paths are caught immediately.

What nono handles

  • Connecting to the Workload API on startup — fails immediately if the socket is unreachable
  • Fetching and injecting the right credential (JWT-SVID bearer or OAuth2 access token via client assertion)
  • Background SVID rotation without process restart or credential interruption
  • OAuth2 token caching and refresh for client_assertion flows
  • Zeroing JWT token memory on drop

What the SPIRE operator handles

Everything else. nono’s interface to SPIRE is the Workload API socket — it has no knowledge of how attestation works, what selectors are in use, or what environment it is running in. The same profile works anywhere SPIFFE runs: Only workload_api_socket changes between environments. The operator’s responsibilities are:
  1. Run the SPIRE server and agent
  2. Register a workload entry mapping nono’s platform identity to a SPIFFE ID:
  3. For JWT routes: configure an OIDC discovery provider so upstreams can verify tokens without any knowledge of SPIRE
  4. For client_assertion flows: configure a federation rule or JWT verification policy on the token endpoint so it accepts the workload’s SPIFFE ID
nono (the supervisor process) is the registered workload — not the process inside the sandbox. The sandboxed process cannot reach the SPIRE socket and has no credential visibility.