agent-consent-bundling Specification
Purpose
Define reference-implementation semantics for agent consent ceremonies that bundle owner approval across multiple configured data connections without turning that bundle into a cross-source PDPP grant.
Requirements
Requirement: Hosted MCP broad approval SHALL issue source-bounded child grants
When the reference hosted MCP flow lets an owner approve multiple sources in one ceremony, the authorization server SHALL issue one independent source-bounded PDPP grant per approved source and SHALL NOT issue a single cross-source PDPP grant.
Scenario: Owner approves multiple sources
- WHEN an owner approves Gmail and Slack in one hosted MCP authorization ceremony
- THEN the authorization server SHALL create one Gmail-scoped grant and one Slack-scoped grant
- AND each grant SHALL remain independently auditable and revocable.
Scenario: Owner denies one source
- WHEN an owner selects Gmail but not Slack in a hosted MCP authorization ceremony
- THEN the authorization server SHALL issue no Slack child grant
- AND the MCP client SHALL NOT receive access to Slack records through the package.
Requirement: Grant packages SHALL NOT be PDPP grants
A grant package SHALL be an authorization-server/reference grouping object for client token routing and audit, not a PDPP grant object carrying source or stream authority.
Scenario: Package token is introspected
- WHEN a package-bound hosted MCP token is introspected by the reference resource server
- THEN the token SHALL identify its grant package
- AND record access SHALL still be authorized only by active child grants.
Requirement: Broad hosted MCP consent SHALL make cumulative risk legible
The hosted MCP consent ceremony for multiple sources SHALL show the owner cumulative breadth before approval.
Scenario: Multiple selected sources include maximal access
- WHEN the hosted MCP ceremony asks for all streams with continuous access across more than one source
- THEN the consent page SHALL show that the approval creates multiple source grants
- AND it SHALL show enough source/stream summary for the owner to understand the cumulative scope.
Requirement: Hosted MCP consent SHALL distinguish configured connections
When a connector has more than one configured owner connection, the hosted MCP consent ceremony SHALL present the configured connection as the owner-facing selectable unit and SHALL preserve the selected connection binding on the issued child grant.
Scenario: Multiple Codex connections exist
- WHEN an owner has more than one active Codex connection
- THEN the hosted MCP consent page SHALL show owner-facing connection names and stable connection identifiers
- AND approving one Codex connection SHALL bind the child grant to that connection instance rather than an arbitrary Codex default.
Scenario: A package selector is ambiguous
- WHEN a package contains more than one child grant for the same connector type
- THEN connector-type selectors SHALL NOT silently choose one child grant
- AND the MCP read path SHALL require a source key, source token, or connection identifier that resolves to exactly one child grant.
Requirement: Package revocation SHALL preserve child-grant control
The reference implementation SHALL support disabling a hosted MCP grant package without removing the ability to audit and revoke child grants individually.
Scenario: One child grant is revoked
- WHEN the owner revokes one child grant in a package
- THEN package reads for that source SHALL stop
- AND package reads for still-active child grants MAY continue.
Scenario: Package is revoked
- WHEN the owner revokes the package
- THEN package-bound access and refresh tokens SHALL stop working
- AND the implementation MAY offer a convenience action to revoke every still-active child grant.
Requirement: Hosted MCP reads SHALL preserve REST read semantics
The hosted MCP adapter SHALL route read tools through the same scoped-token REST resource-server semantics rather than defining independent MCP-only query behavior.
Scenario: MCP search selects a REST search mode
- WHEN an MCP client calls
searchwithmode=hybrid - THEN the adapter SHALL route through the REST hybrid search endpoint
- AND it SHALL forward supported structured query parameters using the same nested REST query shape.
Scenario: A package token searches across children
- WHEN a package-bound MCP token searches across multiple child grants
- THEN each child read SHALL use the same REST endpoint selected by the MCP adapter
- AND each result SHALL remain source-qualified.
Requirement: Hosted MCP connection presentation SHALL use shared connector identity
The hosted MCP consent picker SHALL use canonical connector keys and configured connections as its selectable units. It SHALL suppress stale alias rows, SHALL NOT show URL-shaped manifest identifiers as connector choices, and SHALL preserve selected connection bindings on issued child grants.
Scenario: Legacy local collector alias has a canonical dataful connection
- WHEN both a stale local collector alias and its canonical connector key are present in storage
- AND the canonical connector has a dataful configured connection
- THEN the hosted MCP picker SHALL NOT show the stale alias as a separate owner-facing source.
Scenario: Connector manifest has a registry URI
- WHEN the hosted MCP picker renders a connector-backed source
- THEN the selectable item SHALL identify the connector type by canonical connector key and display name
- AND any registry URI SHALL be shown only as provenance metadata, not as the value submitted by the form.
Scenario: Owner approves multiple connections
- WHEN an owner approves multiple configured connections in one hosted MCP authorization ceremony
- THEN each child grant SHALL bind to the selected canonical connector key and selected connection id
- AND the grant package SHALL NOT infer child grants from connector-type URLs or stale aliases.
Requirement: Grant packages SHALL be visible to the operator
The reference implementation SHALL expose grant packages to the operator console as a first-class artifact that the operator can list, inspect, and revoke without per-child manual revocation.
Scenario: Operator opens the package list
- WHEN the operator visits the package list surface on the operator console
- THEN the surface SHALL render every grant package issued on the deployment, ordered by created-at descending
- AND each row SHALL surface the package id, the bound subject and client, the active status, the count of member child grants, and the created and revoked timestamps.
Scenario: Operator opens a package detail
- WHEN the operator opens a single package on the operator console
- THEN the detail surface SHALL render the package status, the bound subject and client, the created and revoked timestamps, and every member child grant with its source and current status
- AND the detail surface SHALL link to each member child grant's standalone detail surface and to the filtered event-subscription list for the package's children.
Scenario: Operator revokes a package
- WHEN the operator submits the revoke affordance on a package detail surface
- THEN the reference implementation SHALL revoke every active package membership
- AND SHALL flip the package row to
revoked - AND SHALL invalidate the package-bound MCP refresh token on the next exchange.
Scenario: Operator tries to revoke an already-revoked package
- WHEN the operator submits the revoke affordance on a package whose status is already
revoked - THEN the reference implementation SHALL return a typed
already_revokederror envelope and SHALL NOT alter the existing child-grant statuses.
Requirement: Child grants SHALL carry their package linkage on operator surfaces
The reference implementation SHALL surface a child grant's parent package id on the operator console grant list and grant detail surfaces whenever the grant is a member of a package.
Scenario: Operator views the grants list
- WHEN the operator opens the grants list on the operator console
- THEN every grant row whose grant id is present in
grant_package_membersSHALL carry the parentgrant_package_id - AND the row SHALL render a pivot affordance to the package detail surface.
Scenario: Operator views a child grant standalone
- WHEN the operator opens a child grant on the operator console
- AND the grant is bound to a package
- THEN the detail surface SHALL render a pivot affordance to the package detail surface.
Requirement: Grant package visibility surfaces SHALL NOT leak secret material
The reference implementation SHALL NOT include grant-package secret material (refresh-token hashes, opaque package secrets, raw bearer strings) on any operator-visible package list, detail, or event-log surface.
Scenario: Operator inspects a package
- WHEN the operator inspects a package detail
- THEN the rendered payload SHALL NOT contain any refresh-token hash, access-token string, or raw package secret
- AND the rendered payload SHALL only surface non-secret identifiers, statuses, and timestamps already exposed elsewhere in the operator console.
Requirement: Hosted MCP adapter SHALL forward self-calls to a configured internal resource-server base
The hosted MCP adapter SHALL forward its grant-scoped self-calls to a configured internal resource-server base URL when one is present, and SHALL fall back to the advertised public resource when no internal base is configured. This applies to BOTH hosted MCP token paths: the package path (the per-member child RsClient fan-out for an mcp_package token) and the standalone path (the single-bearer RsClient for a client token). The advertised resource, the protected-resource discovery metadata, and the MCP server's advertised providerUrl SHALL continue to resolve to the public origin; the internal base SHALL be used only as the adapter's server-internal fetch base and SHALL NOT be advertised, written into issued-token audience/resource, or returned in discovery responses. The internal base SHALL be operator-configured to a trusted loopback or internal cluster/service-DNS address and SHALL NOT be derived from request headers. Each self-call SHALL still be authorized only by its active grant bearer (the child grant's bearer for a package token; the single grant's bearer for a client token) and SHALL remain subject to per-grant resource-server enforcement.
Scenario: Package-token update recovers from a public-edge method block
- WHEN a hosted MCP package token calls
update_event_subscription(aPATCH /v1/event-subscriptions/:idself-call) - AND the public edge fronting the advertised resource rejects the PATCH method with HTTP 405 while the configured internal resource-server base method-routes PATCH
- THEN the adapter SHALL forward the self-call to the internal base and the update SHALL succeed
- AND the call SHALL NOT return an
rs_errorwith codehttp_405.
Scenario: Standalone client-token update also recovers from a public-edge method block
- WHEN a standalone hosted MCP
clienttoken (not a package token) callsupdate_event_subscription(aPATCH /v1/event-subscriptions/:idself-call) - AND the public edge rejects PATCH with HTTP 405 while the configured internal base method-routes PATCH
- THEN the adapter SHALL build the single-bearer
RsClientagainst the internal base and the update SHALL succeed - AND the call SHALL NOT return an
rs_errorwith codehttp_405 - AND the advertised
providerUrlSHALL remain the public origin.
Scenario: Advertised metadata stays public
- WHEN a client discovers the hosted MCP resource and the adapter forwards a child self-call to the internal base
- THEN the advertised
resource, the protected-resource discovery metadata, and the advertisedproviderUrlSHALL resolve to the public origin - AND the internal resource-server base SHALL NOT appear in any advertised metadata, discovery response, or issued-token audience.
Scenario: No internal base configured falls back to the public resource
- WHEN no internal resource-server base is configured for the deployment
- THEN the adapter SHALL forward child self-calls to the advertised public resource
- AND the package adapter's child-locate, source-selection, ambiguity, fan-out, and per-child enforcement behavior SHALL be unchanged.
Scenario: Internal base does not widen authority
- WHEN the adapter forwards a child self-call to the configured internal resource-server base
- THEN the self-call SHALL carry the owning child grant's bearer
- AND record access SHALL still be authorized only by that active child grant under the resource server's per-grant enforcement.
Requirement: Fast broad agent consent SHALL remain proposed until accepted
Any mechanism that lets an owner approve multiple source scopes for an agent in one ceremony SHALL be treated as proposed until reviewed and accepted through the OpenSpec/spec process.
Scenario: Experimental batch consent ships in the reference
- WHEN the reference implementation experiments with a batch consent or grant package flow
- THEN the UI and documentation SHALL label it reference-experimental
- AND it SHALL NOT claim finalized PDPP protocol semantics.
Requirement: Issued grants SHALL remain source-bounded unless explicitly superseded
Fast setup designs SHALL preserve the current source-bounded grant model by issuing independent grants per source rather than a single cross-source grant, unless a later accepted PDPP change explicitly supersedes that model.
Scenario: Owner approves a multi-source setup ceremony
- WHEN an owner approves access to multiple connectors or providers in one owner-facing ceremony
- THEN the resulting access SHALL be represented as multiple independently revocable source-bounded grants
- AND RS enforcement SHALL remain per grant and per source.
Requirement: Broad consent UI SHALL make cumulative risk legible
Any proposed broad or batch consent ceremony SHALL render enough information for the owner to understand cumulative access risk across sources.
Scenario: A request includes high-risk breadth
- WHEN a staged setup request includes continuous access, all streams, no time range, no field projection, sensitive sources, or many sources
- THEN the consent UI SHALL surface those risk factors explicitly
- AND it SHALL NOT make maximal access visually equivalent to a narrow single-task grant.
Requirement: Owner control SHALL remain granular
Any proposed broad setup flow SHALL preserve granular owner control over approval, denial, audit, and revocation.
Scenario: Owner rejects one source in a package
- WHEN an owner-facing ceremony contains multiple source-bounded requests
- THEN the owner SHALL be able to deny or remove one source without denying all other sources
- AND any approved sources SHALL remain auditable and revocable independently.
Requirement: Client-authored broad packages SHALL be constrained
The AS SHALL NOT accept arbitrary client-authored "all data" packages without validation, risk classification, and owner-visible review constraints.
Scenario: Client requests many maximal continuous scopes
- WHEN a client stages a broad package containing many maximal continuous source scopes
- THEN the AS SHALL either reject it or require a stronger consent ceremony than a narrow request
- AND the owner SHALL see which sources and scope dimensions make the request broad.
Requirement: Hosted MCP picker SHALL let the owner narrow streams within a selected source
When the hosted MCP package picker presents a connector-backed source, it SHALL render an owner-controllable list of the connector's manifest streams alongside the source toggle. Selecting the source SHALL make stream choices available without implying that every stream was approved. Leaving an individual stream unselected, or clearing it after selecting it, SHALL exclude that stream from the issued child grant. The AS SHALL NOT silently widen the issued child grant beyond the streams the picker observed as selected at submission time.
Scenario: Owner selects a subset of streams within a selected source
- WHEN the owner selects a hosted MCP source and selects only some streams within that source before submitting
- THEN the issued child grant SHALL authorize only the streams selected for that source
- AND the AS SHALL NOT include unselected streams in the resulting
authorization_details.
Scenario: Owner explicitly authorizes every stream for a source
- WHEN the owner selects a hosted MCP source and submits every manifest stream for that source as selected
- THEN the AS MAY emit the canonical
[{ name: "*" }]shorthand for that source so the child grant naturally expands when a future manifest revision adds streams - AND the issued child grant SHALL authorize every manifest stream for that source at the time of approval.
Scenario: Owner leaves every stream unselected for a selected source
- WHEN the owner selects a hosted MCP source but submits no stream selected within it
- THEN the AS SHALL NOT silently drop the source or issue a child grant for that source
- AND the AS SHALL re-render the hosted picker with an HTML validation error naming the affected source(s) by display name, not raw connector URLs or internal connection ids.
Requirement: Hosted MCP picker SHALL enforce a selected connection on the issued child grant
When the hosted MCP package picker presents a connector that has more than one active connection and the owner selects one specific connection row, the issued child grant SHALL carry streams[].connection_id for every stream entry it authorizes, including the canonical wildcard entry, so that the selection the owner saw is enforced on every grant-authorized read rather than recorded only as audit or display metadata. When the picker presents a connector with exactly one active connection, or presents only the connector with no connection-level choice, the issued child grant SHALL omit connection_id and preserve cross-connection (fan-in) read semantics. The connection enforced on the issued grant SHALL equal the connection named to the owner in the picker; the AS SHALL NOT enforce a different connection than the one shown, and SHALL NOT silently drop a stale or unknown connection after validation.
Scenario: Owner selects one connection among siblings
- WHEN the owner selects a hosted MCP source whose connector has more than one active connection and chooses one specific connection before submitting
- THEN every stream entry on the issued child grant SHALL carry that connection's
connection_id - AND a grant-authorized read under that child grant SHALL return records only from the selected connection and SHALL NOT disclose records reachable only from a sibling connection of the same connector.
Scenario: Owner approves the whole source for a selected connection
- WHEN the owner selects every manifest stream for a hosted MCP source whose connector has more than one active connection and a specific connection is chosen
- THEN the AS MAY emit the canonical
[{ name: "*", connection_id }]shorthand for that source - AND the issued child grant SHALL constrain every authorized stream to the selected connection, whether the grant stores the wildcard form or its expanded per-stream equivalent.
Scenario: Single-connection source preserves fan-in
- WHEN the owner selects a hosted MCP source whose connector has exactly one active connection
- THEN the issued child grant SHALL NOT carry a
streams[].connection_idconstraint - AND previously-issued single-connection grants SHALL continue to function without re-issuance.
Scenario: Enforced connection matches the shown connection
- WHEN the picker issues a child grant pinned to a connection
- THEN the package member audit metadata (
source_json.connection_id) and the enforceable grant scope (grant.streams[].connection_id) SHALL name the same connection - AND the AS SHALL reject a submitted connection that is not an active binding for the owner and connector rather than issuing a grant pinned to an unknown connection.
Requirement: Hosted MCP picker SHALL let the owner choose the package access mode
The hosted MCP package picker SHALL expose a single owner-facing control that selects the package access mode for every child grant issued by the ceremony. The control SHALL offer the two protocol-enforced access modes (single_use and continuous) defined by spec-core.md. The AS SHALL apply the submitted access mode to every authorization_details[] entry the picker emits; mixed-access packages are out of scope for this picker. The picker SHALL default to continuous to preserve the prior baseline behavior, and the owner-facing copy SHALL describe what each mode means in plain language before submission.
Scenario: Owner accepts the default continuous access
- WHEN the owner submits the picker without changing the access-mode control
- THEN every child grant issued by the package SHALL carry
access_mode: 'continuous' - AND the picker MAY rely on the spec-default
continuoussemantics rather than re-encoding the value into every checkbox.
Scenario: Owner narrows the package to single-use access
- WHEN the owner selects the
single_useaccess-mode control before submitting - THEN every child grant issued by the package SHALL carry
access_mode: 'single_use' - AND each child grant SHALL be subject to the same single-use lifecycle (one consumption, expiry on use) that
spec-core.mdalready defines for non-package single-use grants - AND the AS SHALL NOT silently upgrade a
single_useselection tocontinuousfor any source in the package.
Scenario: Picker rejects unsupported access-mode submissions
- WHEN the picker POST submits an
access_modevalue that is notsingle_useorcontinuous - THEN the AS SHALL return a typed
invalid_requesterror - AND the AS SHALL NOT issue any child grant for the request.
Requirement: Hosted MCP picker SHALL NOT encode a non-Core retention shape
The hosted MCP picker SHALL NOT emit a retention field on the authorization_details[] entries it constructs, and the issued child grants SHALL NOT carry a retention object that does not match the spec-core.md shape { max_duration, on_expiry }. In the generic Claude/ChatGPT hosted MCP ceremony no Core-shaped per-source retention commitment exists; absence is the honest answer, and absence SHALL be how the picker conveys it. The owner-facing copy SHALL state plainly that this ceremony does not encode a machine-readable retention bound on the issued grants, and that any retention of fetched results is governed by the MCP client's own policy and any external agreements the owner has with that client.
Scenario: Picker says the ceremony does not encode a retention bound
- WHEN the picker renders the cumulative-risk disclosure copy
- THEN the copy SHALL state that this ceremony does not encode a machine-readable retention bound on the issued grants
- AND the copy SHALL NOT call this a retention policy encoded in the grant
- AND the copy SHALL NOT advertise an owner-controllable retention preset that the picker does not actually emit.
Scenario: Picker-issued child grants omit the retention field
- WHEN the picker emits an
authorization_details[]entry for a selected source - THEN the entry SHALL NOT include a
retentionobject - AND the issued child grant SHALL NOT carry a
retentionobject whose shape does not matchspec-core.md's{ max_duration, on_expiry }.
Requirement: Grant detail spine events SHALL surface what the package picker approved
Every grant.issued spine event for a hosted MCP package child grant SHALL include the structured fields a downstream operator surface (dashboard timeline, CLI grant timeline, /_ref/grants/:grantId/timeline) needs to recognise a narrowed grant without re-deriving the picker submission. Specifically the event data SHALL include the resolved access_mode and the resolved stream_names from the issued grant, and the event data SHALL make the absence of a machine-readable retention bound visible — either by omitting the retention key or by surfacing it as an explicit null. The event data SHALL NOT include a non-Core retention shape (for example, a classification field).
Scenario: Operator inspects the timeline for a narrowed package child grant
- WHEN an operator opens the spine timeline for a child grant issued by the hosted MCP package picker
- THEN the
grant.issuedevent data SHALL includeaccess_modeandstream_names - AND the event data SHALL convey retention absence as
retention: null(or by omitting the key) when no Core-shaped retention is carried on the grant - AND the event data SHALL NOT include a non-Core retention shape such as
retention.classification - AND a child grant narrowed to a subset of streams SHALL be distinguishable from a wildcard child grant by inspecting
stream_namesagainst the connector manifest at the issued-at time.
Requirement: Batch consent ceremony SHALL stage multiple source-bounded grant requests under a soft cap
The reference implementation SHALL accept a staged consent request that carries more than one source-bounded authorization_details[] entry, up to a reference-contract soft cap, and SHALL present it as one owner ceremony. Each staged entry SHALL carry exactly one source binding; the ceremony SHALL NOT merge entries into a cross-source request. The soft cap and warning threshold SHALL be reference-contract policy constants (default soft cap 8, default warning threshold 6), not protocol limits, and there SHALL be no hard cap. The ceremony SHALL be labeled reference-experimental in the rendered screen, in generated docs/OpenAPI metadata, and in any skill text, until a further OpenSpec change promotes batch consent out of experimental status.
Scenario: Client stages several sources in one request
- WHEN a client submits a staged request with five source-bounded
authorization_details[]entries - THEN the reference implementation SHALL render one owner ceremony covering all five sources
- AND each entry SHALL retain its single source binding without being merged into a cross-source request.
Scenario: Staged entry count crosses the warning threshold
- WHEN a client stages a request whose source-bounded entry count is at or above the warning threshold but at or below the soft cap
- THEN the ceremony SHALL render a warning that the request is unusually broad
- AND the ceremony SHALL still allow the owner to proceed.
Scenario: Staged entry count exceeds the soft cap
- WHEN a client stages a request whose source-bounded entry count exceeds the soft cap
- THEN the reference implementation SHALL flag the request as exceeding the soft cap
- AND it SHALL NOT silently truncate the staged entries without telling the owner which sources were affected.
Scenario: Ceremony is labeled reference-experimental
- WHEN the owner opens the batch consent ceremony
- THEN the rendered screen SHALL carry a reference-experimental label
- AND the label SHALL also appear in generated docs/OpenAPI metadata describing the ceremony.
Requirement: Batch consent ceremony SHALL render per-source review with a cumulative-risk header
The ceremony SHALL show one review card per staged source and one aggregated cumulative-risk header summarizing breadth across the whole batch. Each per-source card SHALL show the source, the requested streams, the fields/projection, the time range, the access mode, and a per-card risk indication. The cumulative-risk header SHALL summarize at least the sensitive-source count, the continuous-access count, the no-time-bound count, the no-field-projection count, and the total stream count across the batch.
Scenario: Owner reviews a mixed batch
- WHEN the owner opens a ceremony staging Gmail, Slack, and a finance source
- THEN the ceremony SHALL render one review card per source showing that source's streams, fields/projection, time range, and access mode
- AND it SHALL render a cumulative-risk header summarizing sensitive-source, continuous-access, no-time-bound, no-field-projection, and total-stream counts across all three sources.
Scenario: Cumulative header reflects maximal access
- WHEN the staged batch requests all streams with continuous access and no time bound across more than one source
- THEN the cumulative-risk header SHALL show that the approval would create multiple source grants
- AND it SHALL show the cumulative continuous-access and no-time-bound counts so the owner can see the aggregate breadth before approving.
Requirement: Batch consent ceremony SHALL support per-source confirmation and per-source partial approval
The owner SHALL be able to act on each staged source independently before approval: approve, deny, defer ("skip for now"), narrow the time range down, and reduce the stream or field set. The owner SHALL NOT be able to widen any staged entry beyond what the client requested. The authorization server SHALL NOT enrich or widen any staged authorization_details entry beyond what the owner reviewed; AS-side narrowing of an over-broad request is permitted.
Scenario: Owner approves a subset of staged sources
- WHEN the owner approves Gmail and Slack but defers the finance source in one ceremony
- THEN the authorization server SHALL issue child grants only for Gmail and Slack
- AND it SHALL issue no finance child grant from this ceremony.
Scenario: Owner narrows one source before approval
- WHEN the owner reduces a staged source's streams from all streams to a single stream before approving
- THEN the issued child grant for that source SHALL be bound to the narrowed stream set
- AND the ceremony SHALL NOT allow the owner to widen any staged entry beyond the client's request.
Scenario: Authorization server does not widen a reviewed entry
- WHEN the owner approves the staged sources as reviewed
- THEN the authorization server SHALL issue child grants matching what the owner reviewed
- AND it SHALL NOT enrich or widen any entry beyond the reviewed scope.
Requirement: Batch consent ceremony SHALL suppress the approve-all affordance under defined risk conditions
A single "approve all" affordance SHALL NOT appear when the staged batch combines continuous access with all streams, pairs no time bound with a sensitive source, or includes three or more sensitive sources. When the approve-all affordance is shown, it SHALL require one confirmation that re-asserts the per-source list. The default presentation SHALL require per-source confirmation rather than offering approve-all.
Scenario: High-risk combination hides approve-all
- WHEN the staged batch combines continuous access with all streams on at least one source
- THEN the ceremony SHALL NOT render an "approve all" affordance
- AND the owner SHALL confirm each source individually.
Scenario: Three or more sensitive sources hide approve-all
- WHEN the staged batch includes three or more sources whose manifest declares
sensitivity: "sensitive" - THEN the ceremony SHALL NOT render an "approve all" affordance.
Scenario: Approve-all shown for a low-risk batch requires a re-asserting confirmation
- WHEN the staged batch does not meet any approve-all suppression condition and the owner uses the approve-all affordance
- THEN the ceremony SHALL require one confirmation that re-asserts the per-source list before issuing grants.
Requirement: Batch consent ceremony SHALL classify source sensitivity from the connector manifest
Connector manifests SHALL be able to declare sensitivity: "standard" | "sensitive". The ceremony SHALL read each staged source's sensitivity from its manifest and SHALL use it for the cumulative-risk header and the approve-all suppression conditions. The reference implementation SHALL NOT hardcode a list of sensitive sources. A source whose manifest does not declare sensitivity SHALL be treated as standard.
Scenario: Manifest declares a sensitive source
- WHEN a staged source's connector manifest declares
sensitivity: "sensitive" - THEN the ceremony SHALL count that source in the cumulative-risk header's sensitive-source count
- AND it SHALL apply the sensitive-source approve-all suppression conditions to that source.
Scenario: Manifest omits sensitivity
- WHEN a staged source's connector manifest does not declare a
sensitivityvalue - THEN the ceremony SHALL treat that source as
standard - AND the reference implementation SHALL NOT consult a hardcoded source list to override that default.
Requirement: Batch consent approval SHALL issue independent source-bounded child grants
Approving a batch ceremony SHALL issue one independent, source-bounded, individually revocable PDPP grant per approved source. The approval SHALL NOT create a single cross-source grant object. Resource-server per-grant enforcement, grant object shape, and revocation semantics SHALL be unchanged from the single-source flow.
Scenario: Approval issues one grant per source
- WHEN the owner approves Gmail and Slack in one batch ceremony
- THEN the authorization server SHALL create one Gmail-scoped grant and one Slack-scoped grant
- AND each grant SHALL remain independently auditable and revocable
- AND no single cross-source grant object SHALL be created.
Scenario: One issued child grant is revoked
- WHEN the owner later revokes the Gmail child grant issued by a batch ceremony
- THEN reads against the Gmail source SHALL stop
- AND reads against the still-active Slack child grant MAY continue.
Requirement: Batch consent approval SHALL group issued child grants under a package for audit and timeline
Approval SHALL record a package_id that groups the issued child grants. The grant timeline and the dashboard SHALL group the issued child grants by their package_id. The package_id SHALL be an authorization-server/reference grouping object for audit and routing, not a PDPP grant object carrying source or stream authority. Per-grant revocation SHALL remain primary; grouping SHALL NOT weaken or replace per-grant revocation.
Scenario: Timeline groups a batch by package
- WHEN the owner opens the grant timeline after approving a batch of three sources
- THEN the timeline SHALL group the three issued child grants under one
package_id - AND each child grant SHALL remain independently inspectable from the grouping.
Scenario: Package id carries no source authority
- WHEN a package-bound token is introspected by the reference resource server
- THEN record access SHALL still be authorized only by active child grants
- AND the
package_idSHALL NOT by itself authorize any source or stream access.
Requirement: Batch consent revoke-package convenience SHALL dispatch per-child revokes with partial-failure visibility
The reference implementation MAY offer a "revoke package" convenience affordance. When used, it SHALL dispatch one revoke per still-active child grant in the package and SHALL surface partial failure, naming which child grants were revoked and which were not. The convenience affordance SHALL NOT replace per-grant revocation, and SHALL NOT silently report success when one or more child revokes failed.
Scenario: Revoke-package succeeds for every child
- WHEN the owner uses the revoke-package affordance and every still-active child grant revokes successfully
- THEN every child grant in the package SHALL be revoked
- AND the affordance SHALL report that every child was revoked.
Scenario: Revoke-package partially fails
- WHEN the owner uses the revoke-package affordance and one child grant revoke fails while the others succeed
- THEN the affordance SHALL report which child grants were revoked and which were not
- AND it SHALL NOT report overall success.
Requirement: Incremental add-source SHALL create a new package linked by parent_package_id
When the same client returns later to add one or more sources, the ceremony SHALL create a new package for the added sources and SHALL link it to the prior package via parent_package_id. The dashboard SHALL render a cumulative per-client view across that client's linked packages. The added sources SHALL issue their own independent source-bounded child grants; linkage SHALL NOT widen or re-issue the previously approved grants.
Scenario: Client adds a source after the initial ceremony
- WHEN a client that previously had a batch package approved returns to add one calendar source
- THEN the ceremony SHALL create a new package linked to the prior package via
parent_package_id - AND it SHALL issue an independent source-bounded calendar child grant without re-issuing the prior child grants.
Scenario: Dashboard renders cumulative client access
- WHEN the owner opens the dashboard for a client that has more than one linked package
- THEN the dashboard SHALL render a cumulative per-client view across the linked packages
- AND each child grant SHALL remain independently revocable from that view.
Requirement: Batch consent ceremony SHALL apply one access mode per package in this tranche
In this tranche, a batch package SHALL apply a single access_mode to every child grant it issues. Per-source access-mode mixing within one package SHALL NOT be offered in this tranche. An owner who needs different access modes for different sources SHALL run separate ceremonies.
Scenario: Package applies one access mode to all children
- WHEN the owner chooses an access mode for a batch package
- THEN every child grant issued by that package SHALL carry the chosen access mode
- AND the ceremony SHALL NOT offer a per-source access-mode control within the package.