Auth and approvals
What std.auth gives you
- JWT verification with real signature checks,
kidresolution, JWKS fetch, andalgenforcement (refusesnone). - API key generation, rotation, and revocation.
- OAuth flows for connector authentication.
- The approval product surface:
corvid approvalsCLI, pending list, approve/deny.
CLI
corvid auth keys generate # generate a new API keycorvid auth keys rotate # rotate signing keyscorvid auth jwt verify --jwks <url> # verify a JWT against a JWKS
corvid approvals pending # list pending approval requestscorvid approvals approve <id> # approvecorvid approvals deny <id> --reason # deny with reasonJWT verification in code
import "@stdlib/auth" as auth
@budget($0.001)agent verify_request(token: String) -> Result<Claims, AuthError> uses auth_effect: let verifier = auth.jwt_verifier({ jwks_url: "https://auth.example.com/.well-known/jwks.json", issuer: "https://auth.example.com", audience: "my-app", }) return verifier.verify(token)The verifier:
- Refuses
alg: none(always). - Refuses tokens whose
kiddoesn’t resolve in the JWKS. - Refuses missing signatures, malformed signatures, expired tokens.
- Refuses tokens whose
issorauddoesn’t match the configured values.
OAuth flow
let oauth = auth.oauth_provider({ provider: "google", client_id_env: "GOOGLE_CLIENT_ID", client_secret_env: "GOOGLE_CLIENT_SECRET", scopes: ["email", "https://www.googleapis.com/auth/gmail.readonly"],})
# Step 1: redirect URLlet url = oauth.authorize_url(state: "csrf-token-123")
# Step 2: in the callback handlerlet token = oauth.exchange_code(code, state)?db.tokens.put_encrypted("google_oauth", customer_id, token)OAuth refresh-token rotation is automatic and uses encrypted storage.
Approval product surface
The approval product is the operator-facing UI/CLI for await_approval
states. From an agent:
agent send_email(to: String, body: String) uses email_effect: await_approval EmailSend(to: to, body_hash: hash(body)) approve EmailDispatch(to) email_send(to, body)The operator sees the pending approval in corvid approvals pending,
reviews the body hash + metadata, and approves or denies. The
agent resumes (or transitions to terminal) accordingly.
Tenant isolation
The job queue + approval queue are tenant-scoped by default. A query
like corvid approvals pending --tenant=customer-A only returns
approvals scoped to that tenant.