Identities and Effective Authority
Separate every principal in an enterprise agent run, then calculate authority as an intersection rather than an inheritance chain.
The enterprise problem and today’s slice
Enterprise problem: An enterprise user can be correctly logged in while an agent still acts with the wrong team, connector, or downstream identity, causing cross-team disclosure or an unauditable external change.
Whole-course context: Days 01–03 produced an owned agent version, a private generated-application boundary, and an admin-provisioned connector grant; today names the separate principals behind those artifacts so none silently inherits another’s authority.
Today’s slice: We model the distinct principals and derive effective authority across the provider control plane, hosted runtime, generated-application plane, and source-owned enterprise systems without granting any cross-plane access implicitly.
End-of-day evidence: A reviewer receives an identity-context contract, an allow/deny decision matrix, and linked records that make every authority input independently revocable and traceable.
Still unsolved: Enterprise login, active-team selection, run-token issuance, per-call connector authorization, human approvals, and mid-run revocation are deliberately deferred.
Thesis: No identity in an agent run lends authority to another; a request is allowed only when independently owned facts intersect for one actor, action, resource, team, deployment, and moment.
The smallest complete model takes a Northstar HelixWorks Supplier Onboarding request, resolves every claimed identity against its owner, and intersects the resulting permissions into one evidence-backed decision. A valid login or workload certificate can enter the model, but neither can skip the current-authority calculation.
Customer outcome and implementation focus
The customer outcome is a reliable, reviewable implementation of 04 identities and effective authority. 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
The pressure to simplify identity context grows with every service hop, but collapsing dimensions makes stale or cross-team authority impossible to diagnose. Keep the context explicit where a dimension can change independently, and compress only evidence that remains traceably resolvable.
| Choice | Benefit | Cost or risk | Use when | Avoid when | Decision rule |
|---|---|---|---|---|---|
| Full typed context | Deterministic checks and rich audit | Larger token or request and more owner lookups | Sensitive runs cross teams, workloads, connectors, or planes | Fields are accepted without owner validation | Carry every decision-relevant dimension; references remain descriptive until resolved |
| Short-lived signed context | Lower lookup cost and tamper evidence | Can become stale before expiry | Freshness window fits the operation risk | Membership, deployment, or connector can change faster than the window | Bound audience and time; revalidate versioned facts when risk or duration exceeds the window |
| Central policy decision point | Consistent rule evaluation and policy revisions | Single service can be unavailable or stale | Resource owners expose current facts and enforcement remains distributed | Central policy is treated as source of every business record | Centralize decision logic, not ownership; owners remain authoritative |
| Downstream service account | Stable machine attribution | Provider may hide the initiating human | Unattended Campaign action needs durable authority | Human-specific downstream ACL must be preserved | Retain a complete platform delegation chain and scope the service account below team policy |
Decisive failures include missing team_id, a deployment from another organization, a trusted workload with no human delegation, an allowed platform decision rejected by the source ACL, and a broken external-request lineage. Deny the action or contain the case, name the failed conjunct, preserve the rest of the evaluated facts, and run an unrelated positive control rather than replacing the failure with a broad role.
Implementation and verification
An authority equation is only a slogan until removing any one input predictably changes the result; without mutation tests, a supposedly required field may be ignored. Implement the Campaign context as a typed contract and verify each owner and conjunct independently.
- Define required fields for organization, active team, human subject, agent and immutable version, deployment, run, workload identity, connector instance, tool, downstream principal, and requested resource.
- Validate syntax, issuer, signature, audience, and expiry, then resolve each opaque reference at the plane that owns it.
- Build the policy input from current membership, explicit run grant, version manifest, deployment binding, connector policy, credential scope, argument constraint, risk rule, and downstream result.
- Evaluate every conjunct and persist its owner, fact version, result, reason, and policy revision even when an earlier check already denies.
- For an allowed external change, append the run, decision, workload attestation, connector decision, provider request ID, and downstream principal to one causal chain.
- Revoke one fact at a time and rerun; keep an unrelated Engineering or read-only request as a positive control.
Minimum acceptance matrix:
| Probe | Expected evidence |
|---|---|
| Complete Marketing Campaign context | Validation digest plus owner resolution for every principal dimension |
Remove team_id | missing_identity_dimension; no default team selected |
| Substitute Sales deployment under Marketing context | Cross-team or cross-organization deny with exact mismatched references |
| Remove each authority conjunct in turn | Every removal flips the target action to deny; unrelated positive control stays allowed |
| Present valid workload identity without delegated run context | Deny; workload trust grants no human or business permission |
| Break connector-decision link for a recorded Slack request | delegation_chain_incomplete and containment case; no guessed edge |
Practical next action and falsifiable evidence
The next useful step is not another role; it is an executable decision table for one Campaign Launch side effect. Encode the complete Marketing context, remove each conjunct one at a time, and require the audit explorer to reconstruct the surviving allowed call from human request to downstream provider receipt.
The thesis is falsified if a missing dimension defaults silently, any single permissive role overrides another owner's denial, a workload certificate supplies human authority, or an external request remains accepted with a broken causal edge. The deliverable is an observable sealed matrix of context digests, fact versions, policy revision, per-conjunct allow/deny outcomes, positive controls, and one complete delegation-chain trace.
HelixWorks repository lab
Make the intersection executable with services/policy-broker/src/domain.ts:
export const claimMatchesGrant = (claim: CapabilityClaim, grant: CapabilityGrant): boolean =>
claim.capabilityId === grant.id &&
claim.tenantId === grant.tenantId &&
claim.runId === grant.runId &&
claim.connectorId === grant.connectorId &&
claim.capability === grant.capability &&
claim.resource === grant.resource &&
claim.argumentDigest === grant.argumentDigest;
The intent is an all-fields match for one Northstar supplier action. The policy-broker runtime interprets it; the separate decision service records the result; CPU compares typed values; the audit record's allowed and reason prove the outcome. This pure predicate has one responsibility (SRP), is reused by every decision path (DRY), and stays independent of storage through a repository port (IoC/DI).
pnpm --filter @helixworks/policy-broker test
Turn each conjunct into one mutation test. Every mutation must deny while the untouched claim allows. Removing tenantId, substituting a run, or changing a supplier resource while preserving allowed: true falsifies the model.