# INFNT™ Auth

INFNT™ Auth is the app-facing identity, token, policy, and agent-delegation
surface for INFNT™ services. Product apps integrate with INFNT™ Auth first; owned
or third-party identity providers are upstream lanes behind this gateway.

## Status

- Browser and app login discovery is active.
- Branded staff/profile login front doors are active at https://auth-staging.infnt.dev/login/infnt and https://auth-staging.infnt.dev/login/chima.
- Clean brand aliases are active at https://auth-staging.infnt.dev/login/brand/infnt and https://auth-staging.infnt.dev/login/brand/chima.
- User identity dashboard is active at https://auth-staging.infnt.dev/dashboard, with https://auth-staging.infnt.dev/profile retained as a compatibility alias.
- PKCE S256 is required for browser authorization-code flows.
- Email staging is the first integrated service catalog entry.
- Human-owned agent review requests are active at https://auth-staging.infnt.dev/agent-requests for signed-in dashboard users.
- Brokered internal QA browser sessions are active behind admin controls.
- Agent action approval controls are active as a protected policy surface for notify-only, per-action human approval, and per-action MFA step-up previews.
- Agent onboarding guidance is active in the internal dashboard API as a generic customer-safe contract.
- Approved registered agents can exchange a signed one-use challenge for a short-lived app token.
- Registered agent keys, when enabled, prove identity only and never grant standing app, broker, or secret access.
- Raw operational secrets are never published through this document.

## Discovery

- Protected Resource Metadata: https://auth-staging.infnt.dev/.well-known/oauth-protected-resource
- Authorization Server Metadata: https://auth-staging.infnt.dev/.well-known/oauth-authorization-server
- OpenID metadata: https://auth-staging.infnt.dev/.well-known/openid-configuration
- JWKS: https://auth-staging.infnt.dev/.well-known/jwks.json
- Application integration: https://auth-staging.infnt.dev/.well-known/infnt-auth-integration

## Register An Application

An application agent may prepare the secret-free `auth.integration.v1`
manifest advertised by the Application integration discovery endpoint. The
agent supplies only stable IDs, exact callback/logout/origin URLs, requested
login methods, scopes, workspaces, and understandable session limits. It must
not supply a provider secret, introspection key, bearer token, private key, or
vault reference.

The Auth owner opens `https://auth-staging.infnt.dev/internal/dashboard#app-connect`,
imports or enters that manifest, reviews the dry run, completes fresh MFA, and
applies the exact reviewed digest. Auth enables the login route last and returns
a durable safe-metadata receipt. Registration preparation is not authorization;
an agent cannot approve its own application registration.

### Google Login

Applications request `google` in `access.login_sources` while keeping
`provider: keycloak`. Google is a federated login source brokered by the managed
OIDC/Keycloak lane; applications must not pass `provider_hint=google` and do not
receive a Google client secret or Google token. They continue to start login
with `provider_hint=keycloak`. The Google button becomes operational only after
the Auth-owned Keycloak realm has its Google identity provider configured and
enabled.

## Browser Login

Human staff/profile login starts at:

- INFNT™: https://auth-staging.infnt.dev/login/infnt
- CHIMA™: https://auth-staging.infnt.dev/login/chima
- Brand alias: https://auth-staging.infnt.dev/login/brand/<infnt-or-chima>
- Dashboard: https://auth-staging.infnt.dev/dashboard
- Profile alias: https://auth-staging.infnt.dev/profile

App-owned browser login starts at:

```text
https://auth-staging.infnt.dev/login?provider_hint=keycloak&app_id=<app-id>&org_slug=<org-slug>&redirect_uri=<url-encoded-callback>&state=<opaque-state>&code_challenge=<S256-challenge>&code_challenge_method=S256
```

The app owns its state value and PKCE verifier for one-time-code app delivery.
INFNT™ Auth owns provider routing, provider-side PKCE, callback completion,
gateway-session delivery, one-time callback-code issuance, token issuance,
JWKS, and introspection.

The branded staff/profile pages are identity-first entry points. They do not
grant product access by themselves; app access is attached later through org
membership, grants, roles, policy mappings, and audit.

## Token Exchange

Exchange the one-time callback code at:

```http
POST https://auth-staging.infnt.dev/oauth/token
content-type: application/json

{
  "grant_type": "authorization_code",
  "app_id": "<app-id>",
  "redirect_uri": "<exact-callback-uri-used-at-login>",
  "code": "<one-time-callback-code>",
  "code_verifier": "<original-pkce-verifier>"
}
```

## Token Validation

Product APIs validate INFNT™-issued access tokens with app/audience checks using
either JWKS verification or server-side introspection:

```http
POST https://auth-staging.infnt.dev/introspect
x-introspection-key: <runtime-only-service-key>
content-type: application/json

{ "token": "<access-token>", "token_type_hint": "access_token" }
```

Do not commit, log, paste, or expose introspection keys. Store runtime keys in
the approved secret store only.

## Agent Proof Token Exchange

An approved agent uses a two-signature proof flow. It first builds the canonical
`infnt.auth.agent_token_challenge_request.v1` payload, binding its agent ID,
app, requested permissions, requested workspaces, token lifetime, registered
public-key fingerprint, issue/expiry times, and a fresh nonce. The agent signs
that request with its registered P-256 private key and submits
`request_payload`, its public JWK, and the base64url signature to
`https://auth-staging.infnt.dev/agent-token/challenges`.

Only after that proof is valid does Auth allocate a short-lived, one-use
challenge. The agent signs the returned canonical `challenge_payload` with
the same private key, then submits `challenge_id`, `challenge_payload`, the
public JWK, and the second base64url signature to
`https://auth-staging.infnt.dev/agent-token/exchange`.

Auth binds the challenge to the human owner, agent, app, audience, permissions,
workspaces, approved actor grant, and requested lifetime. Challenges expire in
minutes and are consumed before token issuance. Agent access tokens last at
most 15 minutes, include the attributable human-to-agent actor chain, have no
refresh token, and never carry provider or vault credentials.

Approval modes are enforced at issuance. `policy_default` and `notify_only`
may receive a scoped short-lived token. `per_action` and `per_action_mfa`
must use the one-use action approval/broker lane and cannot mint a standing
agent access token. Auth stores neither private keys nor proof signatures.

## Service Catalog

| Service | App ID | Audience | Provider hint | Notes |
| --- | --- | --- | --- | --- |
| INFNT™ Email | infnt-email | infnt-email | keycloak | Staging integration active. |
| CHIMA™ Email | chima-email | chima-email | keycloak | Staging redirect/token-proxy integration active. |

## SideClaw / INFNT Network Panel Permissions

INFNT™ Auth reserves these permission strings for the SideClaw/INFNT Network
Panel and backup controls. Product APIs must still enforce route, resource,
tenant, environment, relationship, and broker rules locally.

Network permissions:

- `network:read_tailnet`
- `network:write_tailnet_tags`
- `network:mint_auth_keys`
- `network:write_tailnet_policy`

Backup permissions:

- `backup:read_status`
- `backup:run_smoke`
- `backup:run_metadata`
- `backup:run_host_backup`
- `backup:restore_preview`
- `backup:restore_apply`

Permission separation:

- network:read_tailnet lists only safe Tailnet/device/host metadata.
- network:write_tailnet_tags allows tag preview/apply only.
- network:mint_auth_keys allows scoped auth-key creation only.
- network:write_tailnet_policy is separate and highest risk.
- Do not grant a broad network:admin shortcut by default.

No broad `network:admin` shortcut should be the default customer or operator
permission.

## Network Panel Guardrails

Tailnet tag mutation:

- Tag changes must use preview before apply.
- Preview must show current_tags, requested_tags, added_tags, removed_tags, policy warnings, lockout risk, and required recovery paths.
- Apply must block if a critical host has fewer than two independent management entrypoints.
- Apply must block if the tag change would remove all management or control paths.

Auth key creation:

- Auth keys require expiry.
- Auth keys require explicit scoped tags.
- Generated auth keys may be displayed once only.
- Audit metadata must never include raw generated auth keys, OAuth secrets, machine keys, or node keys.

No raw Tailscale OAuth secret, machine key, node key, or generated auth key may
be returned by an API except the one-time display of a newly generated scoped
auth key to the initiating operator. Audit metadata must use opaque refs,
hashes, counts, tags, expiry, actor, and decision context only.

## Backup Guardrails

- backup:run_host_backup is HQ/internal-only until customer backup products are designed.
- backup:restore_apply is HQ/internal-only until customer restore products are designed.
- Restore apply is materially more dangerous than backup run and must be separately gated.

Audit redaction:

- Audit metadata must never include raw R2 credentials, signed URLs, or sensitive object keys.
- Prefer stable opaque refs or hashes for backup object references.

`backup:restore_apply` is separately gated from `backup:run_host_backup`
because restore apply can overwrite working systems.

## Lightweight Plan And Entitlement Claims

Access tokens stay lightweight. Do not embed large entitlement objects in every
token. Use snapshot IDs and versions, then let product APIs expand server-side.

Supported lightweight claim names:

- `plan_id`
- `plan_tier`
- `entitlement_snapshot_id`
- `entitlement_version`
- `policy_snapshot_id`
- `workspace_ids`
- `brand_id`
- `tenant_id`
- `environment`
- `actor_chain`

`policy_snapshot_id` remains the authorization decision anchor. The
`entitlement_snapshot_id` and `entitlement_version` claims describe product
plan/entitlement state; they do not replace policy snapshots.

Current tenant semantics:

- `org_id` is the Auth identity organization boundary.
- `tenant_id` is the product/runtime tenant boundary.
- First-class brand, tenant, app-contract, entitlement snapshot, actor subject,
  and actor grant tables are defined by migration `014_agentic_os_contract.sql`.
- Legacy sessions without an app contract may still fall back to
  `tenant_id = org_id`; new integrations should register an app contract and
  explicit tenant.

First-class Agentic OS tables:

- `identity_brands`
- `identity_tenants`
- `identity_app_contracts`
- `identity_entitlement_snapshots`
- `identity_actor_subjects`
- `identity_actor_grants`

## Actor Chain Requirement

`actor_chain` is required before broad automation rollout. It should express
the attributable path such as human -> agent -> service/broker/runtime.

Agent and service actions must be traceable to:

- human subject ID
- agent/runtime/service ID where applicable
- `org_id` and `tenant_id`
- `app_id` and `aud`
- `workspace_ids`
- `policy_snapshot_id`
- authorization decision ID or audit decision reference

## Reserved Network/Backup Audit Events

- `network.tailnet_devices_read`
- `network.tailnet_tags_previewed`
- `network.tailnet_tags_applied`
- `network.tailnet_auth_key_previewed`
- `network.tailnet_auth_key_minted`
- `network.tailnet_policy_previewed`
- `network.tailnet_policy_applied`
- `backup.r2_smoke_run`
- `backup.metadata_run`
- `backup.host_backup_run`
- `backup.restore_previewed`
- `backup.restore_applied`
- `agent_request_create`
- `agent_request_read`
- `agent_request_review_preview`
- `agent_request_review_apply`
- `agent_activation_preview`
- `agent_activation_apply`
- `agent_revocation_preview`
- `agent_revocation_apply`
- `credential_broker_provider_upsert`
- `credential_broker_target_upsert`
- `credential_broker_request_preview`
- `credential_broker_grant_issue`
- `credential_broker_invocation_claim`
- `credential_broker_invocation_revoke`
- `credential_broker_invocation_expire`

Audit events must never include secrets, raw Tailscale auth keys, OAuth secrets,
machine/node keys, raw R2 credentials, signed URLs, or sensitive R2 object keys
if those keys reveal private structure. Prefer stable opaque refs or hashes for
backup object references.

## Controlled Agent Registration

INFNT™ Auth treats agents as first-class identities, but agent registration is a
restricted approval lane, not open public signup. Identity creation never grants
product permissions, raw secrets, service tokens, or brokered actions by itself.

Human-owned agent invariant:

- A human Auth account must exist and complete required verification before an
  agent can register.
- The human owner record must carry name, email, phone, address or verified
  org/workspace, and reviewed ID, credential proof, enterprise directory proof,
  or KYC/KYB when risk requires it.
- The agent record must link to the human owner, approving admin, app, org,
  workspace, environment, policy snapshot, relationship tuple, revocation state,
  and expiry.
- Agent signup starts at zero permissions. Approval and policy mappings must
  grant every app role, service token, broker action, and external side effect.
- Every agent action must preserve the paper trail: human owner, agent identity,
  task/workflow, policy decision, broker/credential path, and result event.

Rollout stages:

1. Internal agents only: operator-approved service_auth, short-lived credentials,
   tight audiences, policy version checks, and complete audit.
2. Staff agents: named human owner, workspace/org binding, device or workload
   posture, approval workflow, and revocation drills.
3. Limited public agents: invite/domain allow-list, email verification, CAPTCHA
   or proof/rate controls, abuse scoring, and no default app grants.
4. Global agent availability: still approval-gated, default-deny, and reversible
   by kill switch; only after stale-policy denial, wrong-audience denial,
   introspection revocation, and broker audit have been proven live.

Agent authorization requirements:

- Default deny until a policy mapping grants role, scope, relationship, audience,
  and allowed broker action.
- Every token must be audience-bound, scope-bound, revocable, and checked against
  current policy version.
- Agent accounts must carry owner, purpose, environment, and expiry metadata.
- Brokered operations should execute approved actions without exposing raw
  Forgejo, deploy, provider, HQ Keys, database, Cloudflare, or customer secrets.
- Suspicious registration, token, and broker events should be rate-limited,
  audited, and eligible for automatic quarantine.

Generic agent onboarding:

1. The agent generates or provides public identity material. The private key
   stays with the agent or its approved runtime.
2. The human owner signs in to Auth and requests a bound identity challenge.
3. The agent signs that challenge. The signed proof is submitted with the
   agent request.
4. The operator reviews the request in Auth. Review alone issues no product
   access, no credentials, and no broker powers.
5. Activation creates only the scoped actor grant that the operator approved,
   with an explicit lifetime in minutes, hours, days, months, years, or
   indefinite.
6. Sensitive future actions use per-action approval. The human owner approves
   with fresh Auth MFA evidence from passkey or TOTP. Typed confirmation text
   is audit/intent friction, not the security factor.

One-time agent or browser links:

- One-time links are short-lived secret material until consumed or expired.
- Prefer direct delivery to the intended browser/operator channel.
- Do not paste links into HQ task comments, chat, logs, docs, screenshots, or
  tickets.
- If direct delivery is not possible, use an access-controlled secret-vault
  entry with expiry and narrow reader policy. Store metadata in HQ, not the
  link value.

Brokered browser-session access:

- Internal brokered browser-session access is available only through protected
  operator/admin APIs.
- The current first adapter is Email QA browser testing.
- The broker uses app, org, persona, role, permission, and TTL templates.
- A normal login attempt does not mint a QA or agent browser link.
- Preview responses are metadata-only. Issue responses may return short-lived
  browser material once through an approved transfer path.
- Registered agent keys should be treated like SSH keys only for authentication:
  the agent may hold a private key, while INFNT Auth stores or verifies the
  public side. That key is never enough by itself; each useful session or
  operation still requires policy, app, org, workspace, purpose, TTL,
  revocation, and audit checks.

Only agents that completed the existing human-owner request, proof, review, and
activation lane may use the exchange. Registration or possession of the private
key alone grants nothing; revoked or expired identities and grants fail closed.

## Rollout System Options

These options describe the policy shape consumers should expect. They are not
self-service switches and do not grant access by appearing in metadata.

| Option | Current posture | Required before widening |
| --- | --- | --- |
| Human staff identity | Internal/staging first | verified email, invite/domain policy, audit evidence |
| Customer identity | Product-controlled rollout | app-specific UX, terms, support path, and no default grants |
| Agent identity | Request/review lane only | owner, purpose, environment, expiry, posture, and approval |
| Service credentials | Operator-issued only | app/audience binding, rotation, revocation, and broker audit |
| Secret/broker actions | Broker-owned execution | action allowlist, one-shot use, audit, and kill switch |

Every lane remains default-deny until the app, org, audience, scope, workspace,
relationship graph, policy version, and revocation checks all agree. Product
apps still own domain-specific resource enforcement even when INFNT™ Auth owns
the issuer and policy snapshot.

## Security Rules

- Never ask for or reveal raw Forgejo, deploy, provider, HQ Keys, database, or
  Cloudflare credentials in chat, docs, logs, or prompts.
- Credentials must be app-bound, audience-bound, scoped, revocable, and
  short-lived where possible.
- Privileged external actions should be brokered instead of handing raw secrets
  to agents.
- On any 401 from a previously working credential, discard cached assumptions,
  rediscover metadata, and request a fresh credential through the approved flow.
- Cloudflare Access remains perimeter-only. INFNT™ Auth remains the app,
  session, and token issuer. Cloudflare Access state may be recorded as
  `access_policy_id` or perimeter metadata, but it is not product identity.

## Integration Contact

Use the INFNT™ Auth repo and service handoff docs for implementation issues.
