Application Knowledge and Two-Plane Authorization
Source: How Enterprise Authentication and Authorization Work in an Agent Platform, sections 24–30; extends “Two Planes of Authorization” with provider, hosted-runtime, and generated-application ownership.
The enterprise problem and today’s slice
Enterprise problem: A shared generated application can reveal another team’s knowledge or reuse its credentials when platform membership, runtime reachability, and application roles are treated as one permission, turning ordinary sharing into a cross-tenant breach.
Whole-course context: The incoming evidence is an immutable deployment with explicit user, team, agent, connector, and tool grants; today places application access and knowledge retrieval behind those grants.
Today’s slice: We separate provider/control-plane permission, hosted-runtime workload and network permission, and generated-application tenant, role, session, and row permission while preserving source-system access-control lists.
End-of-day evidence: A reviewer receives positive and denied run traces proving a permitted analyst sees only authorized documents and a target team cannot inherit the source team’s connector or application authority.
Still unsolved: Immediate revocation, long-run cache freshness, production audit export, and adversarial rollout gates remain for later days.
Customer use cases
Sharing an application is dangerous when “can open” is mistaken for “can retrieve everything,” because a successful launch can hide a data leak. These use cases require a useful positive result and an explicit denial at the boundary that owns the rejected authority.
| Use case ID | Actor | Customer job | Success outcome | Denial or recovery evidence |
|---|---|---|---|---|
| D02-UC-01 | Finance analyst using a generated research application | Ask a question over enterprise knowledge without seeing documents outside the analyst’s source permissions | The application answers from security-trimmed chunks and records the exact source ACL version used | A forbidden document is absent, the retrieval denial names the source-policy reason, and an authorized document remains retrievable |
| D02-UC-02 | Customer owner distributing a project, preview, or deployed application | Give builders, revision reviewers, Sales app users, or public intake users only the intended surface without inheriting Marketing credentials, source, preview, or app roles | Separate provider membership, narrow preview capability, Sales-owned deployment/app audience, and route-scoped anonymous policy grant only their declared actions | Cross-plane probes, copied Marketing bindings, wrong revision/tenant/organization, expired links, and anonymous read/export/admin are denied while unrelated intended access stays usable |
The generated application is one platform product, but it spans three independently revocable planes:
| Plane | Owns | Must not imply |
|---|---|---|
| Provider/control plane | Customer organizations, projects, source, immutable versions, deployment policy, collaborators, connector registry, provider audit | Provider project membership does not create an application end user or grant source-document access |
| Hosted-runtime boundary | Artifact digest, environment, secrets, network route, workload identity, deployment instance, isolation | A reachable connector or valid workload certificate does not grant a human or application role |
| Generated-application plane | Application tenants, end users, roles, visibility, sessions, domain rows, authorization predicates | An app administrator does not become a provider builder or bypass connector and source ACLs |
Customers often call three different actions “sharing,” but they are separate products. A project collaborator accepts a single-use, expiring, intended-identity-bound invitation into a named provider role such as Viewer, Editor, or Release Approver over source, agent execution, environment configuration, preview creation, evidence, or release approval. A preview reviewer receives a high-entropy, revision-bound capability over one preview’s audience, methods, environment, expiry, and revocation epoch; the stored record contains only the token hash and cannot reach project APIs or production. A generated-app user receives an app tenant, audience grant, role, resource, and action policy without gaining source or preview authority. Intentional group automation creates distinct grants and audit events rather than a transitive bridge.
Distribution modes define discoverability and route behavior; none changes provider project membership:
| Generated-app mode | Discoverability and authentication | Application authorization | Mutation default |
|---|---|---|---|
| Private | Named app members; authentication required | Current tenant membership plus role, resource, and action | Deny unless role permits |
| Team | Configured app group; authentication required | Materialized or live group admission plus app role | Deny unless role permits |
| Organization | Verified identities from one configured customer organization | Organization admission plus explicit app-tenant and role mapping | Deny unless role permits |
| Unlisted | Possession of a high-entropy app capability reaches only its entry route | Capability audience, method, route, scope, expiry, and app policy | Deny unless explicitly scoped |
| Public | Internet may discover selected routes; authentication optional only there | Route policy; authenticated administration remains separate | Deny by default |
Public discovery never implies public create, read, update, delete, enumeration, export, attachment access, subscription, or administration. A public intake application may deliberately allow one validated anonymous-create route while denying every read and administrative path. Previously downloaded or exported bytes cannot be recalled, so visibility changes state that residual instead of promising erasure.
Invocation surface also matters: a library launch carries an enterprise user and active team; a direct URL carries an app session; an embedded application carries a host-mapped identity; an API carries a client principal; and an agent-to-agent call carries original subject plus actor. A deployment allowlists its surfaces rather than accepting all callers by default.
Actor-centred user stories
Broad stories such as “users can search” conceal which authority is being exercised, so acceptance must expose both allowed and forbidden observations. Each story therefore names the actor, the customer outcome, and evidence that a neighboring plane did not silently grant access.
| Story ID | Use case IDs | User story | Observable acceptance conditions |
|---|---|---|---|
| D02-US-01 | D02-UC-01 | As a Finance analyst, I want every retrieval filtered by my current source-system permissions, so that generated answers cannot reveal documents I could not open directly | An allowed query returns a cited authorized chunk; a probe for doc_legal_918 returns no chunk and a decision ID; both observations record organization, app tenant, user, active team, graph, ACL version, environment, and trace ID |
| D02-US-02 | D02-UC-02 | As a customer owner, I want project collaboration, revision previews, app audiences, and public routes administered as separate grants, so that sharing one surface cannot disclose another or copy Marketing authority into Sales | Provider-only collaborator and revision-bound preview probes succeed narrowly; the publish screen lists unbound capabilities and refuses Marketing connectors; private/team/organization/unlisted/public route matrices show intended allows and cross-plane, wrong-revision, wrong-tenant, anonymous-read/export/admin denials |
The key distinction is between an application package and a deployment. The package contains immutable logic and abstract capabilities such as knowledge.search; a deployment binds one version to one team, invocation surfaces, connector instances, knowledge graphs, risk rules, and environment. Sharing the package never copies those bindings.
End-to-end product flows
An answer can look correct even when it was produced with excessive authority, so the flow must show every enforcement point and terminal proof. “Security trimming” means filtering candidates with current source access-control metadata before any text reaches the model.
| Flow ID | Use case IDs | Path | Trigger | Numbered steps | Terminal evidence |
|---|---|---|---|---|---|
| D02-FLOW-01 | D02-UC-01 | Happy | Finance analyst submits a question in the generated research application | 1. The generated app validates its app session, tenant membership, role, and conversation visibility.<br>2. The provider gateway resolves the linked provider subject, organization, active team, immutable deployment, and allowed invocation surface.<br>3. The hosted runtime presents workload identity plus a short-lived delegated run token.<br>4. The retrieval gateway checks the deployment’s knowledge capability and graph binding.<br>5. The index returns candidates, then filters them by source document ID, source ACL version, allowed principal or group, and maximum classification.<br>6. Only authorized chunks enter model context; the app stores the answer and citations under its tenant. | Evidence envelope records actor usr_fin_42, resource graph_finance/doc_approved_17, scope knowledge.search, precondition acl_version=719, expected authorized chunk only, observed cited answer, environment prod-eu, timestamp, policy digest, and immutable trace_id plus decision_id |
| D02-FLOW-02 | D02-UC-01 | Denied | Analyst asks for a legal document that appears in the shared index | 1. The same app, provider, and workload checks pass.<br>2. Candidate retrieval finds the chunk, but source ACL metadata excludes the analyst and Finance groups.<br>3. The filter removes the chunk before model context assembly.<br>4. The gateway records a deny reason without logging document content.<br>5. A permitted Finance document is queried as an unaffected positive control. | Actor, forbidden resource, scope, ACL precondition, expected denial, observed zero authorized chunks, positive-control result, environment, timestamp, policy digest, and immutable decision and trace IDs |
| D02-FLOW-03 | D02-UC-02 | Happy | Sales administrator chooses “Deploy shared application to Sales” | 1. The provider control plane copies only the immutable package reference.<br>2. It displays required abstract capabilities as unbound.<br>3. The administrator selects a Sales-owned graph and connector instance.<br>4. Policy validates Sales team access, invocation surfaces, and risk constraints.<br>5. The runtime creates an isolated Sales deployment referencing the same artifact digest.<br>6. The generated app creates a separate Sales app tenant and administrator mapping. | Deployment receipt records actor, package digest, Sales scope, empty-binding precondition, expected independent bindings, observed Sales deployment and app tenant, environment, timestamp, and immutable release and audit IDs |
| D02-FLOW-04 | D02-UC-02 | Denied | Sales administrator submits a copied Marketing connector reference | 1. The provider resolves the connector as Marketing-owned.<br>2. Team-access evaluation denies Sales before secret resolution.<br>3. No runtime deployment or app-role mapping is created.<br>4. The credential broker is never called.<br>5. Marketing launches its existing deployment as an unaffected positive control. | Denial records actor, Marketing connector resource, requested Sales scope, team-binding precondition, expected deny, observed no credential access, positive-control result, environment, timestamp, and immutable audit ID |
| D02-FLOW-05 | D02-UC-02 | Denied | Owner invites a builder, mints a preview link, and publishes one anonymous intake route, then probes boundary crossings | 1. Invitation acceptance creates a provider ProjectMembership only.<br>2. Preview service stores a hash-only capability bound to project, environment, revision, methods, audience, expiry, and revocation epoch.<br>3. App policy creates a separate audience grant or one route-scoped public-create rule.<br>4. Builder-to-app, reviewer-to-project/production/later-revision, app-user-to-source, and anonymous read/enumerate/export/admin probes deny.<br>5. Provider source view, bound preview read, intended app route, and anonymous intake creation remain positive controls. | Evidence records each actor, resource, scope, explicit grant precondition, expected boundary result, observed allow or deny, environment, timestamp, grant/policy version, and immutable trace and decision IDs |
Agent-to-agent access uses the same intersection, not the callee creator’s privileges:
callee effective authority =
original user's current authority
AND original team's authority
AND caller deployment's delegation grant
AND callee deployment authority
AND callee capability manifest
The delegated token is audience-bound to the callee, preserves both sub (the human) and act.sub (the calling agent), and carries caller deployment, callee deployment, run lineage, narrow scope, and expiry. Maximum depth, fan-out, tool budget, cycle detection, cancellation, timeout, and spend limits prevent recursion from expanding authority or cost.
System design derived from the flows
If identity, reachability, and data filtering collapse into one service, one bug can grant end-to-end access and ownership becomes unauditable. The design keeps business authorization, workload/network authorization, operation authorization, and source-data authorization as an AND across three product boundaries.
| Use case ID | Entry point | Responsible services | Authoritative store | Failure evidence |
|---|---|---|---|---|
| D02-UC-01 | Generated application question form | Generated-app session and policy service; provider identity, membership, deployment, and authorization services; hosted agent runtime; retrieval gateway; knowledge index; source ACL adapter | App session and domain database owned by the generated app; provider membership/deployment policy store owned by the control plane; ACL metadata index owned by retrieval but versioned against the source system | App-role deny, stale ACL-version rejection, zero authorized chunks, invalid run-token audience, or workload-identity failure, each linked to one trace |
| D02-UC-02 | Provider “Deploy to Sales” action | Sharing service; deployment policy service; connector registry; credential broker guard; runtime deployer; generated-app tenant provisioner | Immutable package and team deployment stores owned by the provider; secret reference and workload deployment state owned by the hosted-runtime boundary; app-tenant membership store owned by the generated app | connector_team_mismatch, missing binding, prohibited invocation surface, no secret-resolution event, and unaffected Marketing run |
The two-plane rule is concrete. The authorization service decides who and what—current user, organization, active team, deployment, capability, connector eligibility, and app mapping. The runtime’s egress proxy decides where and how—source workload, destination host and port, mutual TLS (mTLS, where both peers authenticate), timeout, and connection limit. The retrieval or tool gateway decides whether the exact operation and arguments are allowed; the downstream document system remains final authority for rows and objects. All checks must allow.
Prompt text, retrieved documents, websites, tool output, model reasoning, and generated code are untrusted requests. They can propose knowledge.search or a tool intent, but they cannot supply a trusted team ID, connector ID, role, approval, or policy override. Trusted context comes from identity services, immutable deployment metadata, the connector registry, policy bundles, workload identity, and the generated app’s signed session.
Data model and ownership
Cross-plane identifiers can quietly transfer authority when a foreign ID is treated as proof of permission, so every reference below is opaque until its owning service re-authorizes it. The lifecycle rules prevent sharing, export, or deletion in one plane from silently mutating another plane’s records.
Generated-application database: Required in this slice — the generated application owns app tenants, end-user mappings, sessions, conversations, citations, and row-visibility predicates; it does not own provider membership, deployment authority, connector credentials, or source ACLs.
| Record or entity | Store and owner | Primary key | Foreign key or opaque reference | Tenant key | Material constraint | Lifecycle and deletion | Use case IDs |
|---|---|---|---|---|---|---|---|
| AppTenant | Generated-app database; app tenant service | app_tenant_id | Opaque provider_deployment_id; re-authorized by provider control plane | app_tenant_id | One active app tenant per deployment and customer mapping; mapping grants no provider role | Created after deployment approval; disable blocks new sessions; export app-owned data; tombstone before domain-row deletion | D02-UC-02 |
| AppPrincipalMapping | Generated-app database; app identity service | app_principal_id | Opaque provider_subject_id; never a role grant by itself | app_tenant_id | Unique subject mapping per app tenant; current app role required on every session | Create on invited/approved sign-in; revoke independently; expire sessions; retain minimal audit tombstone | D02-UC-01, D02-UC-02 |
| AppConversation | Generated-app database; conversation service | conversation_id | Local FK app_principal_id; opaque provider_run_id for lineage only | app_tenant_id | Row predicate requires tenant plus owner/shared visibility; citations reference only authorized chunks | Retain to customer policy; export app data; cascade messages on deletion while retaining redacted audit linkage | D02-UC-01 |
| Invitation | Provider collaboration store; invitation service | invitation_id | Local project and intended provider-principal references | organization_id | Single-use, identity-bound, role-bound, expiring, and idempotent acceptance | Expire or revoke before acceptance; retain redacted outcome; purge recipient profile fields after retention | D02-UC-02 |
| ProjectMembership | Provider collaboration store; project service | project_membership_id | Local project and provider-principal references | organization_id | Unique active principal/project role; provider role cannot satisfy preview or app policy | Create from identity-bound invitation; disable independently; retain audit tombstone; cancel affected provider work | D02-UC-02 |
| PreviewCapability | Preview delivery store; capability service | preview_capability_id | Opaque project, preview, revision, and optional provider-principal references | organization_id | Store token hash only; bind audience, methods, environment, revision, expiry, and revocation epoch | Expire/revoke; purge edge cache and close streams; later revisions require new grant; downloaded bytes remain outside recall | D02-UC-02 |
| AppSharePolicy | Generated-app database; app policy service | app_share_policy_id | Opaque application and provider deployment references | app_tenant_id or route-scoped public sentinel | Visibility, audience, protected routes, mutation defaults, and monotonic policy version required | Version rather than overwrite; archive/delete with app after retention; prior exports remain outside recall | D02-UC-02 |
| AppAudienceGrant | Generated-app database; app audience service | app_audience_grant_id | Local FK app_share_policy_id plus app principal/group/organization or public-audience reference | app_tenant_id or route-scoped public sentinel | Grant type, audience, scope, role, expiry, and revocation version required; grants no provider or preview authority | Revoke independently; tombstone until sessions/streams/jobs converge; purge after audit retention | D02-UC-02 |
| CapabilityLink | Generated-app database; app capability service | capability_link_id | Local FK app_share_policy_id and route; token represented only by hash | app_tenant_id or route-scoped public sentinel | Binds audience, method, route, scope, expiry, and epoch; possession grants no administration | Expire/revoke and purge caches; delete token hash after retention; state download residual | D02-UC-02 |
| TeamDeployment | Provider deployment store; control plane | deployment_id | Local FK agent_version_id; opaque runtime release and app-tenant references | organization_id plus team_id | Immutable version; explicit surfaces and bindings; package sharing never copies bindings | Draft, approve, activate, disable, supersede; retain digest and audit; delete bindings only after runtime retirement | D02-UC-01, D02-UC-02 |
| KnowledgeBinding | Provider capability registry; control plane | knowledge_binding_id | Local FK deployment_id; opaque graph_id owned by retrieval | organization_id plus team_id | Graph must be approved for the deployment team and classification ceiling | Create during deployment; independently revoke; retain binding revision and decision evidence | D02-UC-01, D02-UC-02 |
| IndexedChunkSecurityMetadata | Retrieval index; retrieval owner, synchronized from source authority | chunk_id | Opaque source_document_id plus source_acl_version | organization_id | Candidate returned only when team, principal/group, and classification predicates all pass; index never becomes ACL authority | Reindex on ACL change; quarantine stale versions; delete chunk on source deletion; retain content-free sync proof | D02-UC-01 |
| DelegatedRunTokenRecord | Provider authorization evidence store; token service | token_jti | Opaque subject, actor, caller deployment, and callee deployment references | organization_id plus active team_id | Audience-, scope-, deployment-, and time-bound; effective authority is intersection, never union | Short expiry; revoke by version/event; retain hashed claims and decision lineage, never bearer token | D02-UC-01, D02-UC-02 |
The index may cache allowed_principals, group IDs, classification, and source_acl_version, but the source system remains the data authority. A cache entry whose ACL version cannot meet the deployment’s freshness policy fails closed. Likewise, app citations store source IDs and decision lineage, not copied source permission.