08

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 campaign manager 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.

Thesis: Opening a generated application, reaching its runtime, and reading enterprise knowledge are three different permissions; safety comes from requiring all three, not from letting any one stand in for the others.

The smallest complete model follows Northstar's HelixWorks Supplier Onboarding Agent from an application session, through one approved deployment, to source-authorized knowledge. A valid app role can start the path, but only the deployment binding and the source access-control list (ACL) can decide which supplier document reaches the model.

Customer outcome and implementation focus

The customer outcome is a reliable, reviewable implementation of 02 application knowledge and two plane authorization. This day introduces the mechanism before policy detail and evidence review; it does not repeat the same customer stories in prose, tables, and diagrams.

Components in focus

Authorization policy service owns decisions; the connector/runtime gateway owns enforcement. Compute: API and isolated worker processes. Storage: PostgreSQL is authoritative for grants and state; Redis is a versioned cache; vault owns secrets; object storage retains redacted evidence only.

Implement the mechanism

Implement the day’s boundary with a current, explicit decision before privileged compute or a downstream call. Bind every effect to a tenant, subject or workload, deployment, resource, and short-lived evidence ID; a cache or model response never grants authority.

Failure modes, trade-offs, and decision rules

Application distribution creates legitimate tension between easy access and independently revocable authority; flattening that tension into “shared” makes later containment unreliable. Choose each sharing mechanism by the exact surface and residual risk it introduces.

ChoiceBenefitCost or riskUse whenAvoid whenDecision rule
Team-level corpusSimple, predictable shared knowledgeCannot express per-document human differencesEvery team member is allowed the same approved corpusSource ACLs differ by user or groupUse only when the source owner can state one uniform audience for the corpus
Document-level trimmingPreserves fine-grained source permissionsRequires ACL synchronization, freshness policy, and negative probesSharePoint, Drive, Slack, or other user-variable sourcesACL metadata cannot be kept current enoughFail closed on stale ACL versions; never compensate with prompt instructions
Expiring preview capabilityLow-friction review of one revisionPossession risk and downloaded-byte residualReviewer needs one environment and revisionProject editing or production access is requiredBind token hash, identity/audience, methods, revision, expiry, and revocation epoch
Public route policyAnonymous reach for a deliberately narrow actionNo enterprise identity and higher abuse riskPublic intake or demo route has no private capabilityRead, export, admin, private knowledge, or enterprise connector is neededDefault every route and mutation to deny; open only the named action

The decisive failure modes are cross-plane role reuse, copied bindings, stale ACL metadata, unauthorized bytes entering model context, and public or preview capabilities reaching adjacent routes. A correct recovery revokes the smallest owning record, expires sessions or caches that depend on its version, and proves an unrelated intended path still works.

Implementation and verification

Security trimming is easy to claim and difficult to demonstrate; without byte-level ordering and paired probes, a denied answer may still have exposed forbidden text to the model. Implement and verify the Campaign Launch path from the outside inward.

  1. Create the Marketing app tenant, manager mapping, role, session, conversation visibility predicate, and opaque link to deploy_marketing_prod.
  2. Configure Campaign Agent v17 with abstract knowledge.brand-guidelines; bind the Marketing deployment to graph_marketing without embedding graph authority in the app session.
  3. Index an allowed brand chunk and forbidden doc_legal_918 with source document ID, ACL version, groups, and classification.
  4. Query candidates, apply current ACL predicates, and assemble model context only from the filtered set.
  5. Store answer citations with source IDs, ACL version, policy digest, decision ID, and trace ID; never copy source permission into the citation.
  6. Deploy the same package to Sales with empty bindings, then bind only Sales resources and create a separate app tenant.
  7. Exercise provider collaborator, preview reviewer, app user, public intake, Marketing retrieval, and Sales deployment matrices at their exact surfaces.

Minimum acceptance matrix:

ProbeExpected evidence
Marketing manager retrieves Brand GuidelinesCited authorized chunk, ACL version, policy digest, decision and trace IDs
Same manager probes doc_legal_918Zero authorized chunks before context assembly; allowed brand document still succeeds
Sales installs Campaign Agent v17Same package digest, new Sales deployment and app tenant, no Marketing bindings
Sales submits Marketing connector or graph referenceDeny before credential or source retrieval; Marketing positive control remains healthy
Preview token requests production or later revisionDeny by audience/revision; bound preview remains readable
Anonymous caller reads, enumerates, exports, or administersDeny; only the explicitly configured public action remains allowed

Practical next action and falsifiable evidence

The architecture is useful only if Acme can show that forbidden source bytes never entered Campaign Launch context and that sharing v17 copied no authority. Build one Marketing and one Sales deployment fixture, execute the six paired probes, and make the release gate consume their sealed evidence.

The claim is falsified if an app role grants provider access, a Sales deployment resolves a Marketing binding, stale ACL metadata is accepted beyond policy, doc_legal_918 appears in model input, or a preview/public capability reaches an adjacent route. The deliverable is one observable evidence bundle linking package digest, deployment and app-tenant IDs, ACL versions, context-chunk hashes, all allow/deny decisions, and unaffected positive controls.

HelixWorks repository lab

Use the shared boundary in packages/contracts/src/http.ts before adding application-specific permissions:

export const requestContextSchema = z.object({
  tenantId: tenantIdSchema,
  subjectId: z.string().min(1).max(128),
  roles: z.array(z.string().min(1).max(80)).max(32),
  correlationId: z.string().uuid(),
});

The intent is to admit a typed provider request, not grant supplier-document access. Zod interprets the schema at the HTTP edge; validation creates trusted in-process context; CPU and memory perform parsing; an accepted correlation ID or rejected tenant ID is the evidence. One contract package is DRY, while keeping document ACL decisions out preserves SRP and the two-plane boundary. Controllers validate this model, application services authorize it, and views render results: MVC does not collapse the planes.

pnpm --filter @helixworks/contracts test
pnpm --filter @helixworks/evidence-projector test

Probe tenantId: "northstar" and tenant_northstar. The first must reject and the second parse. The model is falsified if an unscoped ID parses, evidence crosses tenants, or adding an application role changes a source ACL decision.