Skip to content

Let agents organize credentials and groups in one approved batch #162

Closed

Description

@sudoHG

Goal

Add an MCP tool organize_credentials that applies a batch of group operations (move credentials, create, rename and delete groups) as one frozen write with one approval and one system authentication.

Context

Executor: Codex · high. risk:security.

Decisions

  1. Operations, at most 64 per batch, applied in order: {"move": {"credential": "<name>", "group": "<name>" | null}}, {"create_group": "<name>"}, {"rename_group": {"from": "<name>", "to": "<name>"}}, {"delete_group": "<name>"}. Credentials are identified by their visible name, as in run.
  2. The whole batch is validated before it is frozen and commits in one transaction. If any operation is invalid, or any affected credential changes, expires or becomes Hidden before commit, nothing is applied.
  3. The catalog gains a top-level groups list: empty groups and groups with at least one visible member. A group whose members are all Hidden, or only recycled, is not listed, and agents get the generic not-found error for it.
  4. Renaming a group moves all its members, including ones agents cannot see. Deleting a group ungroups all its members, as the App does, and deletes no credential. For both, the approval card states the affected count, for example "4 credentials, 1 not visible to agents". Renaming onto an existing group name is rejected; agents merge groups with moves.
  5. The approval card lists every operation in order: moves as "name: from → to", created groups, and renames and deletions with their member counts. Approval, digest, retransmission, expiry and cancellation behave as for other agent writes.
  6. Agents cannot change permissions or delete credentials through this tool.

Approved design (Step 1 gate, 2026-10-08)

  • New .organize approval operation. BrokerApprovalOperationRequest gains an optional sorted, unique organizationCredentialIDs binding (affected credentials, including Hidden and recycled members of renamed or deleted groups); single-credential requests require it nil. Organize uses an empty credentialID and the target credential-library. There is one ticket per batch and no per-member tickets. Equality and consumption include the binding, and cancelPending matches any member. The binding and every affected name or count stay App-side and never appear in any response to the agent.
  • Expiry: only credentials explicitly moved by the batch must be unexpired, and only their expiry can shorten the request deadline. Members affected only by a group rename or delete, Hidden or recycled ones included, neither block the batch nor shorten its deadline. Expiry-triggered cancellation uses a separate Broker cancelPendingForExpiry(credentialID:). It still cancels reads and single-credential writes, but keeps an organize batch whose own deadline, derived only from moved credentials, is still valid. Only the expiry-triggered calls in Vault+CredentialDelivery.swift and Vault+AgentWriteFreeze.swift switch to it, with no run or delivery behavior change. Ordinary cancelPending still matches every batch member when a credential actually changes.
  • The approval digest binds the ordered operations, caller data, the before and after state of affected records, and the state of the groups the batch names. It does not bind the whole group list, so unrelated App group edits do not invalidate a pending batch. One SQL transaction re-validates that state and writes records, groups and the existing idempotency receipt.
  • Moves need a destination that is visible or created earlier in the batch. Renaming onto any occupied name, including a group agents cannot see, fails with the generic error. Rename and delete include recycled members, matching App group management, and the card counts them as not visible to agents.
  • Access records: one .modify event per affected credential, Hidden included, plus one credential-less .modify event for a group-only batch. Denial uses the same binding.
  • Card: the existing 300-point prompt with caller, details and expiry; every numbered operation in a height-capped scroll area (moves as name: from → to, created groups, renames and deletes with total and not-visible member counts); no material reveal; Approve Organization and Deny within 680 points in English and Simplified Chinese.

Scope

May change: helper MCP definitions, parsing and guide; broker action, approval operation and summary types; vault freeze and commit for the batch; the approval card and its strings; ADR 0010 (append the approval shape); docs/features.md; the CI screenshot scenario in Tests/AskKeyE2ETests/ScreenshotE2ETests.swift, its synthetic MCP write in Tests/AskKeyTestSupport/E2EBrokerScenario.swift, and its entry in the scripts/e2e-report.py allowlist; tests in Tests/AskKeyBrokerTests/, Tests/AskKeyVaultTests/, Tests/AskKeyAppTests/.

Must not touch: run and delivery; permissions; the App's own group management UI; BrokerProtocolVersion.

Steps

  1. Design gate. Propose how a multi-credential write is represented in BrokerApprovalOperationRequest, the request store and the access records, with the approval-card layout. Send it to the coordinator as an Orca question and wait for approval before writing code.
  2. Broker types and the catalog groups list.
  3. Vault: validate, freeze and commit the batch atomically.
  4. Helper: the organize_credentials schema, parsing and guide text.
  5. App: the approval card and strings.

Acceptance

swift build
swift test --filter <changed suites>
python3 scripts/check_hygiene.py && python3 scripts/check_module_deps.py
  • Tests: mixed batch commits all-or-nothing; one invalid operation rejects the batch; a stale, expired or newly Hidden member fails the commit; rename to an existing name is rejected; renaming or deleting a group that includes Hidden members applies to them and the summary counts them; deleting a group deletes no credential; a hidden-only group is absent from groups and unknown to agents; the 64-operation limit; one approval and one authentication per batch; Allow and timed allowances do not skip approval.
  • CI build-and-test and basic-ui-flows green, and the approval-card screenshot from CI is linked in the PR. The screenshot step is continue-on-error, so report the screenshot test's own result as well as the job result.

Blocked by

#161 (agent metadata writes).

Activity

  1. added
    enhancementNew feature or request
    ready-for-agentFully specified; an agent may claim it
    risk:securityTouches broker, approval, delivery, crypto or keychain; requires line-by-line review
    on Oct 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestready-for-agentFully specified; an agent may claim itrisk:securityTouches broker, approval, delivery, crypto or keychain; requires line-by-line review

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions