/** * Outbound grant expression building. * * Builds a composed grant expression for kernel calls: * grant = union(credential(delegationJWT), self) * * The kernel resolves this by verifying the delegation JWT (kernel-signed) * to get the caller's scoped identity, and resolving self to the function's * identity. Union means either identity's permissions work. */ import type { Delegation } from '@astrale-os/kernel-core' import { createUnresolvedGrant, unresolvedCredential, unresolvedSelf, unresolvedUnion, } from '@astrale-os/kernel-core' /** * The composed identity expression: union of the caller's delegated access * (a kernel-signed credential leaf) and the function's own identity (self). * * Used both as the grant on outbound kernel calls AND as the delegation * expression when minting a NEXT-HOP credential — the next worker receives * principal = this function, authority = union(caller's delegated, own). */ export function buildComposedExpr(delegation: Delegation) { return unresolvedUnion(unresolvedCredential(delegation.credential), unresolvedSelf()) } /** * Build the grant expression that unions the caller's delegated access * with the function's own identity. * * @param delegation - Delegation extracted from the inbound credential * @returns The unresolved grant object with version and expression */ export function buildComposedGrant(delegation: Delegation) { return { grant: createUnresolvedGrant(buildComposedExpr(delegation)) } } /** * The SELF-ONLY expression: the function's own identity, nothing delegated. * Used by `ctx.fn.kernel()` sessions (public/webhook handlers acting on their own * authority) — both as the credential grant and as the next-hop delegation. */ export function buildSelfExpr() { return unresolvedSelf() } /** Self-only grant for function-owned credentials. */ export function buildSelfGrant() { return { grant: createUnresolvedGrant(buildSelfExpr()) } }