Resource scoping at preference assignment

Status: provisional recommendation, 2026-10-12. Human reviewer: ___ / date: ___ / outcome: ___. This is design work; the optional scoping contract, generic scope editor and derived-resource lifecycle are not implemented. Track reconciliation in DEVLOG. Reuse the existing preference and grant model, baseline contracts and contribution lifecycle.

Recommendation

Let a resource optionally implement a scoping contract that describes the restrictions its provider can actually enforce. When the owner assigns that resource to a preference field, the host presents supported typed controls and stores the selected resource plus scope configuration as the field value. That scope applies identically to every authorized consumer of the shared field. Applications receive an enforceable scoped resource reference and an appropriately granted token in place of the private field configuration. Consumer applications keep using ordinary resource/contract/method invocation.

The canonical private field value is conceptually {resource, scope}. A derived scoped resource is a useful implementation of its application-facing reference, not an alternative place for the user's configuration. The existing RPC envelope identifies a resource, contract and method; it carries no preference-field identity. Resolve each field assignment revision to a scoped reference whose private binding unambiguously identifies that assignment and scope. A distinct URL permits existing RPC dispatch to enforce the selection without the consumer resubmitting scope configuration. The child is a view over existing storage or service state, not a copy or new provider connection. Other provider implementations are acceptable if they enforce the same exact binding and token boundary.

This is useful generalization: storage namespaces, inbox subsets and method restrictions belong to the resource implementation that understands their semantics. Avoid a global collection of provider-kind flags that guesses what “folder,” “read-only” or “account access” means. Unsupported resources remain assignable under their existing whole-resource semantics, with that scope shown explicitly; a resource cannot advertise narrower access unless the server enforces it.

Minimal optional contract

An illustrative immutable identifier is https://spec.bindle.example/contracts/resource-scoping/v1. This is a placeholder, not a published or implemented contract. Final schemas and method names need review before publication.

Method Proposed role
describeScopes({}) Return a pinned scope schema/revision, supported restriction profiles, inert labels/help, bounds, and exact candidate contract/method ceilings for this resource. Return only information visible to the authenticated caller.
Scope resolution The authenticated assignment workflow validates and normalizes {schemaRevision, schemaDigest, selection} and asks the resource provider for an enforceable scoped reference. This can be internal for a local provider. A remote provider needs an explicit reviewed resolution method; its exact contract and delegation rules are follow-on work.

Keep schema discovery separate from authority. Merely describing controls neither produces an access token nor grants a parent resource. The assignment workflow stages the private field value and scoped binding against the displayed preference revision, with durable idempotency. Initial app connection still needs ordinary consumer consent. An owner change to an already shared field can approve the reviewed fanout in one save as described below. Cancellation must not leave newly authorized consumers or unbounded abandoned child records. Do not introduce a public factory or registry solely to render the controls.

The schema describes a bounded declarative subset: booleans, bounded strings/numbers, enums, exact method selections and explicitly supported typed selectors. No JavaScript, HTML, CSS, arbitrary widget URLs, executable expressions, remote schema references or app-supplied confirmation logic. An authenticated, separately authorized bounded selector can supply choices only where a reviewed profile defines its information exposure. It cannot covertly add object listing to the storage contract. Unknown restrictions or unsupported form features fail closed; hiding a field must never relax its restriction. Validate on the server regardless of browser validation.

Provider-specific presentation can explain a standard restriction profile without changing it. A schema version/digest pins meaning; the stored canonical selection is immutable and separately fingerprinted. App suggestions are untrusted defaults for review, never authority. Cosmetic metadata changes can follow the existing safe presentation policy; changed restriction semantics require a new schema revision and new child resource.

Identity, authority and enforcement

The provider assigns each child a fresh, stable canonical HTTPS URL, for example https://identity.example/entities/e1/resources/r-scoped-7. The URL is an identifier, never a bearer credential. Private records bind owner, parent resource, parent lifecycle generation, pinned profile/schema, normalized selection, permitted methods, enforcement binding and child lifecycle generation. App-facing descriptors expose only approved contracts/methods and safe health information; the owner editor can show the full scope summary. Consumer projections omit scope configuration, the raw parent reference, upstream tokens, endpoint credentials, native provider identifiers and private configuration. An app need not learn or be able to call the parent URL.

Initially only the provider's authenticated owner assignment interface may create or replace bindings, with its normal session, Origin and CSRF checks. Advertising the scoping contract does not grant resolution/creation authority to applications. If remote-provider resolution or future delegated creation is useful, grant an exact reviewed method on a specific authorized parent; the server must prove attenuation against that caller's current authority and all ancestors. It cannot accept an app-selected owner, arbitrary parent or broader upstream credential. General owner management authority and an app's resource-method grant remain different caller contexts.

Each call resolves the child before provider effects and intersects:

  1. The caller's live token and exact current resource/contract/method grant, bound to the consumer, fragment, field and approved assignment revision.
  2. The child's immutable restriction and every active ancestor restriction.
  3. Current owner/resource relationships, connection and lifecycle generations, verified adapter capabilities and provider policy.

Constrain arguments and outputs as needed; read filters alone are insufficient for writes, moves, deliveries, presigned links or callbacks. Out-of-scope exact reads must not disclose hidden existence. Journal fingerprints retain the addressed child and resolved binding; cached private results receive live authorization checks. An asynchronous operation rechecks applicable generations before authoritative publication. Parent disconnect/revocation stops new child calls; a child revoke affects that child and descendants. Reconnect cannot silently revive revoked child grants, even when reconnect preserves underlying storage mappings. Export/backups must preserve child restrictions and ancestry alongside mappings; tokens/grants do not migrate automatically.

Bound ancestry, child count and staged records, forbid cycles and cross-owner references, and validate attenuation using a reviewed restriction profile. For an initial implementation, one child level and explicit supported profiles are enough. Do not introduce a generic policy expression language or attempt to infer arbitrary predicate containment. Broader credentials held inside the provider never substitute for the child's restriction. Already admitted external effects or issued bearer URLs retain their documented limitations; scope changes cannot recall disclosed data.

A child advertises the same exact baseline contract only when its restricted behavior remains compliant with that contract's capability-negotiation rules. Method ceilings do not make an adapter conformant. When a contract requires unsupported methods or forbids the proposed filtered semantics, use a compliant narrower contract/version or decline creation. Never relabel arbitrary app tools as storage or inbox contracts merely because their inputs look similar.

Shared field configuration and consumer tokens

Preference values belong to the owner and immutable fragment version, not the requesting app. If two apps use the same field, both receive references governed by the same selected resource and scope. The editor has one scope configuration and shows every affected consumer. Existing method permissions may differ: an app already approved only to read stays read-only, while an app approved to read/write can use both within the shared scope. Each consumer receives a distinct token bound to its own identity/grants; tokens do not encode different user-selected field scopes. Other fields and independently approved resources can still provide additional authority, which access-removal explanations must disclose.

An owner can change shared scope for all affected consumers in one deliberate save after reviewing the concrete targets, old/new scope and resulting access for those consumers. Do not require separate per-app scope choices or repeated approvals. The single save is the owner's explicit approval of that disclosed shared change, including an intentional widening within existing contract/method rights. It does not approve additional methods, new consumers, changed contract semantics or unrelated resources.

Bind that review to the current fragment/field revision, exact affected active consumers, their relevant grant revisions, selected resource and pinned normalized scope. Commit the new private value, resolved binding and updates to the shown consumers' assignment/resource approvals atomically, or fail closed while reconciling if remote provisioning prevents a single transaction. A changed consumer set, grant, schema or assignment requires fresh review; the previously displayed save cannot authorize an unseen consumer or effect. Previously revoked consumers stay revoked. Restoration of access that was explicitly removed is a separate visible effect, never inferred from an old historical grant.

Current federation grants pin exact resource URLs and configuration removes old resource approvals. Therefore this shared-save fanout is an explicit proposed extension of the owner approval/configuration workflow, not behavior already supplied by configure. Do not silently bypass existing checks when the scoped URL changes. Preserve each consumer's current method ceiling, record the reviewed assignment transition and approval, and issue new tokens against that committed binding. Unapproved/missing assignments keep existing requiresConsent behavior. Newly connected apps require their normal consent even when the shared field is already configured.

Each stored assignment revision and its enforcement binding are immutable. Changing scope creates a new revision/binding; a stable underlying child URL must not let an old token silently acquire wider access. The simplest first implementation issues a fresh scoped URL and revokes the old field binding on commit. Old tokens fail for that binding; freshly issued tokens reflect the reviewed new revision. Narrowing/removal blocks new work immediately. Other fields still intentionally using the old underlying resource are unaffected unless the owner explicitly revokes the resource itself. Existing in-flight effects and bearer links follow their documented revocation limits.

The current preferences contract returns {id, label, contracts} and uses the session's application bearer for RPC; it does not yet return per-field resource tokens. The proposed consumer projection is conceptually {resource: {id, label, contracts}, token, expiresAt} in place of the private field value. Its exact versioned wire schema remains review work. Tokens are short-lived opaque capabilities bound to issuer, subject, consumer, resource audience and the reviewed assignment/grant revision. The provider resolves grants server-side and enforces revocation; a broad parent bearer beside an ignored scope object is not this feature. Tokens are credentials, never public descriptors, logs, cache keys, URLs or executable metadata. Remote resource token issuance/introspection and revocation require the existing separately reviewed provider trust boundary; local gateway support does not prove arbitrary external providers support it.

Examples

Managed object storage. The owner selects their managed Drive resource for an application's syncStore field, chooses the logical namespace apps/notes/, and allows read/write without deletion or presigning. The child exposes exact-key object operations under its allowed method ceiling. Prefer a reviewed namespace profile with explicit relative-key translation: child key directory.json maps to parent logical key apps/notes/directory.json. Validation preserves exact Unicode semantics and prevents adapter traversal/aliasing; the same logical parent object must share its authoritative version/precondition state across all overlapping views. Do not maintain independent child CAS authorities over the same object. All paths, including cached reads, signing and internal dependencies, must apply the same mapping.

Applications maintain their known directory/index object; scoping adds no enumeration. Read/write is offered only when the actual parent adapter supports the required conditions. The managed Drive implementation uses immutable remote payloads and atomic host mapping publication. A logical key prefix is not a Google-native folder grant, OAuth scope reduction or upstream Drive compare-and-swap. Its existing credential custody, single mapping authority, retained physical payloads and real-account verification limits still apply. See managed Drive architecture and storage semantics.

Inbox subset. A future reviewed inbox profile may permit exact selected inbox IDs, allowed methods and a bounded, precisely defined membership filter. The profile must say whether future matching messages enter the view; that dynamic rule is the scope the owner approves. A label or UI search string is not an authorization predicate. Direct item lookup, pagination, counts, subscriptions, writes and delivery must all enforce the same scope, including when membership changes. Existing conversation membership and messaging capability checks still apply. This is an example profile, not a claimed implemented filtered-inbox contract.

Implementation boundary and next step

The existing federation service provides immutable fragment schemas, owner registerResource/configure, exact resource/method grants, current-assignment checks and missing-value consent behavior. Its constructor/dispatch injection points and internal resource registration are implementation mechanisms, not already a public resource factory or delegated app-management API. The generic contribution registry, upstream importer, scoping schema, child records, parent enforcement and scope UI remain separate work. Current registerResource accepts only its documented fields; adding metadata alone would not enforce this design.

Implement one provider-owned namespace fixture first, through the normal owner assignment and consumer consent path. Verify overlapping-view atomicity, path/Unicode isolation, out-of-scope reads and writes, stale revisions, shared-field affected apps, explicit reviewed shared fanout on widening and no revival of revoked consumers, parent/child revoke, reconnect generations, cached-result authorization and absent credentials in descriptors. Include actual DOM/browser checks for scope review and supported typed controls, plus npm test for SDK/core/server changes. A second provider fixture should demonstrate the same profile without a provider-brand special case before claiming portability. This document changes no production code or release gate.

Provisional decision Human sign-off
Optional provider-enforced scoping contract; owner selects restrictions during preference assignment. Reviewer ___ / date ___ / outcome ___
Store scope in the shared private field value; project enforceable scoped references and consumer-specific tokens. Reviewer ___ / date ___ / outcome ___
Owner assignment resolves scope initially; any remote resolution or future delegation is proven attenuation with normal exact method grants. Reviewer ___ / date ___ / outcome ___
One reviewed owner save can change shared scope for the disclosed consumers; preserve each consumer's existing method permissions and invalidate stale bindings. Reviewer ___ / date ___ / outcome ___

Independent review clarification: affected consumers are those with currently effective authorization for this exact field and its old binding, including current resource approval and method ceilings. A broad list of active fragment grants is not sufficient; consumers of unrelated fields and previously pruned/revoked bindings must not be revived. Namespace adapters return child-relative keys and sanitize errors, metadata and signed-link outputs so the parent prefix and native provider identifiers do not leak. Initial conformance fixtures must exercise these output boundaries as well as input attenuation.

Credential rotation and refresh are not themselves scope changes. Implementations must distinguish a preserved source identity/restriction from a revoked lifecycle epoch; reconnect cannot restore a revoked field grant. Native presigned URLs that expose private parent configuration cannot satisfy the opaque projection profile without an approved opaque/proxy representation.