# drksci / id protocol notes The id.drksci.com surface describes identity cards, delegated grants, and human approval. Enforcement belongs to the authenticated gateway. ## Request flow 1. An agent presents its stable identifier and public key. 2. It requests a resource, actions, environment, and expiry. 3. The registered parent may approve within its delegated scope. 4. Otherwise the request bubbles to the parent chain. 5. The human operator receives a notification and opens the approval URL. 6. The operator authenticates with Cloudflare Access and approves or declines the exact request. 7. The gateway issues a short-lived grant and records its decision. A child grant is the intersection of parent authority, policy, and requested scope. It cannot outlive its parent. ## Environments Use `local`, `dev`, `preview`, `staging`, or `production`. An omitted or unknown environment is treated as production policy. ## Notifications Web Push may be implemented with VAPID. The single `id-worker` Worker may use a Durable Object for subscriptions and delivery. Production configuration requires `VAPID_PUBLIC_KEY`, `VAPID_PRIVATE_KEY`, and `VAPID_SUBJECT` in the secret store. The fallback is a Cloudflare Access protected approval URL with operator OTP. The notification is never an authorization artifact. Tapping a notification only opens the approval page; it cannot approve, grant, or revoke anything. Local development has no secret requirement. Without a configured gateway, the static pages provide discovery and examples only. ## Feedback and debugging Could this run smoother? What were you trying to do? Use `/feedback/` after an action or failed flow. The form carries optional expected outcome, observed result, and safe reproduction steps, plus a generated `correlation_id` and path-only `page_path`. It submits a sanitized JSON body to `POST /api/v1/feedback` with `credentials: omit`; it never sends cookies, tokens, bearer headers, private keys, the query string, or local git credentials. Common secret formats are redacted before submission, but users must still leave secrets out. `FEEDBACK_ENABLED` is the deployment flag. The feedback mirror/outbox uses the root [`feedback.md`](../feedback.md) format: append one sanitized record, retain the correlation ID, retry transient failures with a bounded backoff, and move repeatedly failing records to a poison queue with an operator-visible reason. Agents should submit the smallest useful report and must not include credentials. ## First-touch onboarding and service catalog The `/catalog/` page lists service types, capabilities, workspace parent-child bindings, and verification states (`verified`, `pending`, `unverified`, `disabled`). Auto-discovery may create a pending record while it checks repository, parent workspace, environment, and DNS CNAME/TXT evidence; pending onboarding never grants authority. Open `/onboarding/` for the first-touch flow. It can display a service URL and repository hint derived from an explicit safe URL parameter or a local git remote supplied by the client. The page explains GitHub App installation, Cloudflare application/domain authorization, and DNS verification in one concise approval card. No provider permission opens until the operator explicitly approves. The server-side start endpoint must issue state and PKCE, reuse an existing approved GitHub session when available, and accept only same-origin path return URLs. Local git credential helpers are never read or uploaded as bearer secrets. After verification, issue only a bounded grant for the verified repository, full canonical workspace chain, declared actions, and explicit environment. The optional `/assist/` page is a feedback analyst. It shows recurring friction, a suggested recipe or rule, confidence, and evidence, then requires explicit review with Apply or Ignore. Apply does not mutate policy here and remains a separate authorized action. `ASSISTANT_ENABLED` controls the page; an optional Cloudflare Workers AI binding named `AI` may provide analysis, with a deterministic local fallback when unavailable. The assistant must never grant access or apply a rule autonomously. After explicit approval, provider actions may open the configured GitHub repository setup, `drksci-id-worker` App installation, Cloudflare dashboard, or deploy workflow. The deployment still requires `CLOUDFLARE_ACCOUNT_ID`, `CLOUDFLARE_API_TOKEN`, environment-specific D1 IDs, and the runtime secrets documented by the infra contract. Wrangler remains the fallback. Provider links open only after the approval card, and return URLs are same-origin paths only. ## Client setup Coding agents should read repository-local `AGENTS.md`, `CLAUDE.md`, and Cursor rules before acting. These files guide discovery; the gateway remains the authority. MCP-capable desktop clients connect to `https://id.drksci.com/mcp`. They first fetch `/.well-known/oauth-protected-resource`, then `/.well-known/oauth-authorization-server`, and use the resulting OAuth metadata. The token must identify the agent Carte ID and be audience-bound to the MCP resource. Local stdio clients use the native OS keychain or environment injection. GitHub Actions use OIDC plus repository or environment secrets. Cloudflare Workers use Wrangler secrets and bindings. Each client should use its own native secret feature when available. Credentials must never be committed, placed in prompts, or written to logs. Workspace and environment come from the trusted `.id.drksci` repository binding and gateway policy. A client must not promote a caller-supplied value over that policy. When a client lacks MCP or OAuth support, it should print or open the authenticated `https://id.drksci.com/ask/{request_id}` URL. That URL is a request and approval interface; opening or receiving it does not approve anything. ## Human passkey step-up Keep Cloudflare Access or the configured IdP as the primary human sign-in, with OTP as recovery. After an authenticated operator session, enroll a WebAuthn credential with `navigator.credentials.create()` and use `navigator.credentials.get()` for high-risk approvals. Bind the relying-party ID to `id.drksci.com` and verify the exact HTTPS origin, challenge, user, origin, RP ID, and signature server-side. Chrome desktop/Android passkeys and phone QR handoff are supported by the browser; the service stores only the credential ID and public key, never a raw passkey or private key. Revoke a credential by ID and provide authenticated recovery through Access/IdP and OTP. ## Workspace-qualified email aliases `codex@plane.id.drksci.com` is an exact verified routing selector for the `plane` workspace. It is not identity or authority. `codex@id.drksci.com` is global only through an explicit alias mapping. Never trust From, Reply-To, or email text alone: verify signed Agentmail metadata and the actor's active grant. Auto-accept only bounded non-production requests under workspace policy. Unknown or expired aliases reject. Environment prefixes are policy hints; missing environment means production policy. ## Client setup and recovery Coding agents read `AGENTS.md`, `CLAUDE.md`, and Cursor rules. MCP clients use `https://id.drksci.com/mcp` and discover `/.well-known/oauth-protected-resource` followed by `/.well-known/oauth-authorization-server`. Local stdio clients use the native OS keychain or environment injection. GitHub Actions use OIDC and repository/environment secrets. Cloudflare Workers use Wrangler secrets and bindings. Use each client's native secret facility, never commit credentials, and derive workspace/environment from trusted repository and gateway policy. If MCP/OAuth is unavailable, print or open the authenticated `/ask/{request_id}` URL. Back up durable policy and audit through the `drksci/id-data` Git mirror; D1 remains live state and the transactional outbox must be replayable after recovery. ## Pre-mortem and KISS defaults Assume the first deployment failed. Check these likely causes: - Aliases were treated as auth, a workspace/domain was not registered, or an alias was recycled. Use exact verified selectors, signed Agentmail metadata, active grants, and a reserved-subdomain registry. - An email scanner consumed a one-time link, an environment was mismatched, or no environment was supplied. Use short-lived single-use links, show the target environment, and treat missing environment as production. - A parent chain cycled or a token survived revocation and clock skew. Detect cycles, use bounded expiries with clock tolerance, check revocation at the gateway, and fail closed. - Webhooks arrived twice or out of order, or a direct origin bypassed the edge. Verify signatures, event IDs, ordering/version, and expose no alternate origin route. - OAuth callback and Access boundaries were confused, passkey RP/origin was wrong, or push subscriptions went stale. Bind callbacks and passkeys to the exact host/origin, require authenticated step-up, remove stale subscriptions, and never let notification delivery approve. - D1 and Git mirror lag, GitHub User-vs-Org permissions, provider plan limits, Paperclip's lack of local provisioning, or broken backups caused surprises. Keep D1 authoritative for live decisions, record mirror lag, scope the GitHub App to actual provider capabilities, configure Paperclip credentials through its supported path, and test restore of `id-data`. The default is one Worker, one live authorization store, one durable mirror, short-lived grants, explicit environments, native secret storage, and fail-closed behavior whenever a dependency or verification step is unavailable.