Application identity
Runku separates application identity from end-user identity. OAuth/OIDC identifies a functional user; Application Keys identify the software context invoking Runku.
These credentials do not administer the installation. Human operator bootstrap, scoped grants,
Management API sessions, and optional workforce OIDC are documented separately in
Platform operator identity. An rk_sec_* key remains an application/server
credential and is never accepted as operator authority.
Application Keys
rk_pub_*identifies browser, mobile, desktop, or other distributable clients. It is not a secret and receives only policies explicitly allowed for public applications.rk_sec_*authenticates trusted server processes, backend integrations, agents, and CI jobs. It must never enter a browser bundle or mobile binary.rk_dev_*authorizes development operations such as Workspace synchronization and freeze. It does not invoke application Functions.
An Environment can have multiple named keys. Keys support one-time reveal, overlapping rotation, independent revocation, and per-key logs and metrics.
Functional identities
An invocation policy selects one of these modes:
none: no functional identity is required;optional: no principal is accepted, or a supplied principal must validate;guest: Runku issues a bounded anonymous identity;user: an external JWT/OIDC identity is required;service: a trusted service identity is required.
Runku validates issuers, audience, time bounds, signatures, and JWKS snapshots. It does not replace the application's identity provider. Better Auth, an enterprise IdP, or another OAuth/OIDC provider can issue the user token.
HTTP shape
A public client sends its publishable key using the public application-key header and a guest or
user token using Authorization: Bearer. A server client uses its service key from server-only
configuration and may also forward an end-user bearer token when the Function policy requires user
context.
Key type, functional identity, Function visibility, target, and Environment protection are all checked server-side.
Client design and browser/server boundary
An Application Client defines kind and maximum scopes; each credential receives a subset. Create separate clients for browser apps, backends, CI, and integrations so rotation/compromise is bounded.
| Runtime | Credential | Functional token |
|---|---|---|
| Browser/mobile/desktop | rk_pub_* | guest or user JWT |
| Trusted BFF/backend | rk_sec_* | delegated user JWT or service identity |
| Workspace/Release automation | rk_dev_* | not an invocation credential |
A valid JWT without an Application Key is rejected. Never put rk_sec_* or rk_dev_* in public
environment prefixes, bundles, HTML, URLs, mobile binaries, analytics, or browser storage.
optional authentication accepts either no functional principal or a validated one; code must
handle both explicitly.
JWT/OIDC trust
Configuration fixes issuer, audience, algorithms, JWKS policy, claim mapping, clock tolerance, and maximum lifetime. Discovery/JWKS access is bounded, HTTPS-only outside loopback, redirect-controlled, size-limited, and last-known-good cached. Signing-key rotation needs bounded old/new overlap without algorithm/key-type confusion.
Authentication does not grant ownership. Functions still enforce membership, roles, and resource-level policy.
Rotation, revocation, and incident response
- create a replacement while the old credential remains active;
- deliver it through the correct public/secret channel;
- deploy and verify logs for the replacement credential ID;
- revoke the old key and monitor stale consumers;
- delete only after revocation and evidence/rollback policy.
Secret material is revealed once and belongs in a secret manager. Lost secret keys are replaced, not recovered. For exposure, scope by client/credential/Environment, rotate/revoke, inspect correlated logs, rotate downstream secrets when needed, and preserve evidence. Log pruning does not revoke credentials or erase exported/backed-up copies.
Authenticated Management API
The Management API exposes the same durable Application Client and credential repository used by
the Product gateway. Every route is scoped by the exact Project and Environment in its path and
requires an rk_at_* operator session; Application Keys never authorize these routes.
| Method and path suffix | Capability | Semantics |
|---|---|---|
GET /application-clients | credentials:read | Complete non-secret client list |
POST /application-clients | credentials:manage | Create or exactly replay a caller-ID-pinned client |
GET /application-clients/{client}/credentials | credentials:read | Complete non-secret credential list |
POST /application-clients/{client}/credentials | credentials:manage | Create a caller-ID-pinned credential |
POST .../{credential}/reveal | credentials:read | Re-derive only a publishable key after digest verification |
POST .../{credential}/rotate | credentials:manage | Create a replacement while preserving the source |
POST .../{credential}/revoke | credentials:manage | Idempotently and irreversibly revoke |
DELETE .../{credential} | credentials:manage | Tombstone an already-revoked credential |
All suffixes are below
/v1/projects/{projectId}/environments/{environmentId}/application-clients. Creation requests pin
canonical IDs and timestamps so clients can distinguish exact replay from conflicting reuse.
Public-key creation is repeatable because the key is deterministically re-derived and verified.
Confidential-key creation and rotation are deliberately not retried after an ambiguous transport
failure: the server never stores plaintext and a second random value conflicts with the durable
digest. Use a new replacement ID or rotate after inspecting the non-secret list. Responses carrying
key material and every error response are Cache-Control: no-store.