docs: clarify credential completion and Slack consent boundaries

Record the actual-auth completion and revocation baselines, final passing qualification, and measured rate-window fixture failure. Name the addressed-human consent step for Slack authorization and installation while retaining source-only coverage.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
DottaandPaperclip committed 2026-10-26 18:41:02 -05:00
1 parent b74c34e75b
commit 9dd4814c9d
3 files changed
+18 -6

No files matched your search

@@ -35,6 +35,8 @@ Binding and audience authorization checks field presence, including `null`, `fal
Generic chat configure/reconnect treats signing/webhook secrets, private keys, client secrets and project secrets as human credential entry. A delegated request returns the saved endpoint's addressed handoff before provider work or vault mutation. Verified provider provisioning can still save provider-selected credentials. Authorized bot-token and API-key entry remains delegated. Generic tool-connection updates cannot replace channel credential references and bypass the provider setup boundary.
Credential-entry intents capture opaque generations for the requested fields. Vault persistence changes a field's generation only when its value changes, and commits those markers plus the active-endpoint verification fence with the new references. Retries preserve the original baseline. Old health, unrelated bot-token repair and unchanged key entry cannot satisfy a replacement request. Changed signing/webhook keys also require renewed webhook verification, and continuation rechecks task and current authority. Credential-entry cards without a completion boundary fail closed; ordinary authentication handoffs are unchanged. Saved credential links open the reconnect form.
Agent setup responses retain their browser fields and add `requiredUserAction` where a human step is needed. It identifies the addressed user, saved resource, setup destination, reason and continuation. Chat handoffs reuse the saved endpoint and existing connection-intent delivery. AI login handoffs reopen the saved sign-in intent in the existing credential UI. Completion is based on server state; the UI does not ask a human to certify setup success.
Generic app OAuth returns the saved setup destination without creating agent-bound provider state; the human browser starts the existing session-bound authorization flow. Its `expiresAt` is null until that human step creates an expiring provider session. Slack/GitHub provider callbacks preserve human subject and state checks. Agent-created GitHub setup binds its browser session when the addressed human opens it. Identity callbacks validate the current human and session before consuming state, and revalidate authority before saving identity. Wrong-user callbacks leave the rightful user's flow intact. Continuation rechecks task state and current authority after a yielding run; cancelled tasks and revoked access cannot be revived by a late provider result.
@@ -207,3 +209,13 @@ Security review found that generic Slack reconnect accepted an agent-chosen sign
The first diagnostic used `configure` on an already configured endpoint and returned the expected lifecycle 409 rather than exercising reconnect (`/tmp/parity-chat-signing-red.log`). Reusing that database then hit the known Slack identity fixture collision (`/tmp/parity-chat-signing-red-reconnect.log`). Fresh databases established the two security baselines above. The first full post-fix run passed all 55 authenticated cases but failed an OpenAPI assertion that expected `anyOf` instead of the emitted `oneOf` (`/tmp/parity-chat-signing-full-green.log`). The final clean PostgreSQL `parity_review_41` run passed all **82 API/OpenAPI tests** (`/tmp/parity-chat-signing-final-full.log`). Eight focused native receipt protections also passed in `/tmp/parity-chat-signing-green.log`. Server typecheck/build passed (`/tmp/parity-chat-signing-types.log`, `/tmp/parity-chat-signing-build.log`). No live provider claim is added.
Linux CI run `40415124314` failed two existing rate-admission assertions because persisted admissions now also record the bucket identity used by paired caller/target checks (`/tmp/parity-e5-linux-failure.log`). The local baseline reproduced both failures (`/tmp/parity-rate-bucket-red.log`). Updating the expected shape first used the wrong fixture field (`/tmp/parity-rate-bucket-green.log`); using the actual actor identity then passed all **49 policy service tests** (`/tmp/parity-rate-bucket-final-green.log`). No production rate behavior changed for this correction. The companion preserves the catalog creator-attribution follow-up so the implementation review stays at 99 changed files. Both PRs must ship together. Fresh current-head Linux CI and reviews remain required; no full local test-sweep pass is claimed.
### 2026-10-26: credential-entry completion and in-flight revocation
The `c8cc70ae30` review correctly found that an already active, healthy endpoint could satisfy the new credential-entry card without human entry. The actual-JWT Slack baseline failed with an available connection instead of `null` (`/tmp/parity-credential-completion-red.log`). Implementation `805d165bc3` persists opaque per-field generations only for changed protected values, fences old active state in the vault-reference transaction, saves the requested field baseline, and preserves it on retries. Completion requires the requested change, active healthy state, renewed signing verification when applicable, and current task/user/agent authority. No secret or value-derived hash is added to the intent.
The expanded journey proves pending state before human entry, after unrelated bot-token repair, after re-entering the old signing key, after changed entry without verification, and across retries with the original baseline. New verification allows normal continuation; cancellation or responsible-user suspension still denies it. A later fixture assertion initially lost the hidden generation by copying the redacted API setup back into the database (`/tmp/parity-credential-completion-final.log`). The fixture now preserves the persisted setup. Two focused cases and four neighboring real-database Slack/GitHub provisioning, reconnect, rotation and concurrency cases passed (`/tmp/parity-credential-completion-green.log`, `/tmp/parity-credential-completion-neighbors.log`).
An added actual-auth race then suspended the responsible user inside provider authentication. The request returned 403 but had replaced refs (`/tmp/parity-credential-commit-revocation-red.log`). Configuration now reauthorizes before persistence and inside the reference transaction, so revocation leaves the original refs intact. Final **82 API/OpenAPI tests passed** in fresh PostgreSQL `parity_review_48` (`/tmp/parity-credential-completion-qualified.log`), and final server typecheck/build passed (`/tmp/parity-credential-completion-commit-types.log`, `/tmp/parity-credential-completion-commit-build.log`).
The preceding full run had one unrelated rate assertion fail as two calls crossed a minute boundary (`/tmp/parity-credential-completion-final-green.log`). The fixture database recorded consumed counters at 23:35 and 23:36 for the same policy and bucket (`/tmp/parity-credential-completion-rate-window-evidence.log`). Rate cases now freeze only `Date`; transport and asynchronous timers remain real. No production rate behavior changed. The final run above includes all rate cases. Companion Slack authorization/installation map entries now explicitly describe the required addressed-human browser-session and consent step; those individual operations retain source-only evidence. Fresh current-head CI and reviews remain required.
+5 -5
View File
@@ -58,8 +58,8 @@ Gaps: This individual operation has source review but no recorded HTTP verificat
### `post-chat-endpoints-slack-managed-authorize`
API: `present` — `POST /api/chat-endpoints/{endpointId}/slack/managed/authorize`; JSON REST.
Agent access: `available` — agent REST and default native `search_api` / `call_api`.
Policy: `tools:manage_connections`; [shared management policy](../../doc/plans/2026-10-13-connection-api-parity.md#authorization-contract). Resolved resources and every affected target are checked; personal ownership remains the responsible user.
Agent access: `available` — agent REST and default native `search_api` / `call_api` return a saved `requiredUserAction` handoff. The responsible user must open that setup, bind their browser session, and consent to Slack access. An agent call does not start provider consent.
Policy: `tools:manage_connections`; [shared management policy](../../doc/plans/2026-10-13-connection-api-parity.md#authorization-contract). Current agent and responsible-user authority bound the request. The addressed human starts the existing session-bound Slack authorization flow; callback state and subject checks remain enforced.
Evidence: `source-only` — [route](../../server/src/routes/chat-channels.ts); reviewed in the working tree based on the source commit above.
Verification: `not-run` — individual operation not executed in this audit; shared authorization and representative family flows are exercised by the authenticated integration suite. Follow the route schema, inspect persistence/audit, and assert owner, scope and revoked-authority denial.
Gaps: This individual operation has source review but no recorded HTTP verification. Provider availability and live setup remain unqualified.
@@ -103,8 +103,8 @@ Gaps: This individual operation has source review but no recorded HTTP verificat
### `post-chat-endpoints-slack-install`
API: `present` — `POST /api/chat-endpoints/{endpointId}/slack/install`; JSON REST.
Agent access: `available` — agent REST and default native `search_api` / `call_api`.
Policy: `tools:manage_connections`; [shared management policy](../../doc/plans/2026-10-13-connection-api-parity.md#authorization-contract). Resolved resources and every affected target are checked; personal ownership remains the responsible user.
Agent access: `available` — agent REST and default native `search_api` / `call_api` return a saved `requiredUserAction` handoff. The responsible user must open that setup, bind their browser session, and consent to the Slack installation. An agent call does not start installation consent.
Policy: `tools:manage_connections`; [shared management policy](../../doc/plans/2026-10-13-connection-api-parity.md#authorization-contract). Current agent and responsible-user authority bound the request. Only the addressed human starts session-bound installation; callback state and subject checks remain enforced.
Evidence: `source-only` — [route](../../server/src/routes/chat-channels.ts); reviewed in the working tree based on the source commit above.
Verification: `not-run` — individual operation not executed in this audit; shared authorization and representative family flows are exercised by the authenticated integration suite. Follow the route schema, inspect persistence/audit, and assert owner, scope and revoked-authority denial.
Gaps: This individual operation has source review but no recorded HTTP verification. Provider availability and live setup remain unqualified.
@@ -268,7 +268,7 @@ API: `present` — `POST /api/chat-endpoints/{endpointId}/setup`; JSON REST.
Agent access: `available` — agent REST and default native `search_api` / `call_api`. Agent-supplied signing/webhook secrets, private keys, client secrets, and project secrets return a saved human credential-entry handoff. Authorized write-only bot-token and API-key setup remains delegated.
Policy: `tools:manage_connections`; [shared management policy](../../doc/plans/2026-10-13-connection-api-parity.md#authorization-contract). The service rejects delegated verification-key entry before provider work or vault writes. Human sessions and verified provider handoffs retain credential entry; agent configuration uses the responsible user's current authority.
Evidence: `verified` — [route](../../server/src/routes/chat-channels.ts); reviewed in the working tree based on the source commit above. [Authenticated fixtures](../../server/src/__tests__/connection-management.integration.test.ts) passed with database persistence and actual bearer/session middleware.
Verification: `passed` — actual key/JWT configure/reconnect requests return the addressed handoff with unchanged secret refs and vault signing value. A human session configures Slack; an agent can repair its bot token and send a policy-governed test message. Native setup receipts are protected. No live provider qualification.
Verification: `passed` — actual key/JWT configure/reconnect requests return the addressed handoff with unchanged secret refs and vault signing value. The saved card stays pending through old health, bot-token repair, unchanged signing-key entry and retries. It completes only after a protected value change, renewed webhook verification and current authority; cancellation or user revocation still denies continuation. Credential-write revocation during provider authentication leaves refs unchanged. A human session configures Slack; an agent can repair its bot token and send a policy-governed test message. Native setup receipts are protected. No live provider qualification.
Gaps: Provider fixtures do not qualify live provider setup or availability.
### `post-chat-endpoints-setup-secret`
+1 -1
View File
@@ -29,7 +29,7 @@ Message the configured bot/address from its external provider and follow the cor
### `endpoint-management`
Delegated setup can save ordinary bot tokens and API keys. Provider verification keys require the addressed human credential-entry step or verified provider provisioning. Generic setup returns the saved handoff without changing those keys, and generic connection updates cannot replace channel credential references. The actual-auth Slack fixture covers both guards and permitted bot-token repair; live provider repair remains separately qualified.
Delegated setup can save ordinary bot tokens and API keys. Provider verification keys require the addressed human credential-entry step or verified provider provisioning. Generic setup returns the saved handoff without changing those keys, and generic connection updates cannot replace channel credential references. A replacement card waits for an actual protected-value change and restored verification; old health, unchanged entry and unrelated bot-token repair do not complete it. The actual-auth Slack fixture covers these boundaries, retries, revocation and permitted bot-token repair; live provider repair remains separately qualified.
Open `/apps/chat/:endpointId/settings` and the endpoint’s other available tabs; identity confirmation uses `/chat-identity/confirm`.