Deterministic evaluation: (intent, state, policy) → ALLOW | DENY. OxDeAI controls execution, not behavior.
No valid authorization → no execution through the enforced guard boundary.
Agents propose actions. OxDeAI decides if they are allowed to execute. Without this boundary, there is no enforced control over what agents can do.
Agents can call APIs, provision infrastructure, move money. You need a boundary that holds before any side effect occurs.
Four outcomes. No path to execution without a valid authorization artifact.
No valid authorization → no execution path.
The Policy Decision Point (PDP) decides. The Policy Enforcement Point (PEP) enforces. The Verifier checks trust. Execution cannot proceed through the guard without a valid authorization.
AuthorizationV1 artifact
issued.trustedKeySets.trustedKeySets
must be configured explicitly by the verifier. In strict mode, missing
key sets →
TRUSTED_KEYSETS_REQUIRED. A valid signature from an unknown issuer still fails closed.
Properties derived directly from the protocol spec and conformance tests.
intent, trusted
state, policy,
and trusted evaluation time. The reference engine has no ambient
randomness or shared mutable state, so restarts and replicas of it
produce identical decisions.
ReplayStore. Nonce window tracking per
agent. Redis-backed replay protection is available for durable
deployments. TOCTOU tests are part of the conformance suite.
trustedKeySets must be configured by the
verifier. In strict mode, missing key sets →
TRUSTED_KEYSETS_REQUIRED. A valid
signature from an unknown issuer still fails closed.
VerificationEnvelopeV1
draft) with state snapshots and event sequences. Envelope
signatures are optional: an envelope is authenticated only when
the verifier sets
requireSignatureVerification with
trustedKeySets. Without it, verification
proves structure, not origin. By contrast, the guard always
verifies AuthorizationV1 signatures in
strict mode before execution.
@oxdeai/guard and are exercised in CI.
Trusted execution context is established at the boundary. Actions execute only after authorization succeeds.
main. The guard setup and
strict verification examples run on the published
@oxdeai/core@2.0.0 and
@oxdeai/guard@2.0.0. Guard-enforced
delegation recipient binding is on main only
and is not in @oxdeai/guard@2.0.0; the
delegation example shows the explicit check 2.0.0 requires.
import { PolicyEngine, RECOMMENDED_TRUSTED_TIME_PROFILE, type Intent } from "@oxdeai/core";
import { createSecureGuard, createTrustedExecutionContext, defaultNormalizeAction, type ProposedAction,
OxDeAINormalizationError, OxDeAIProvenanceConflictError, OxDeAIDenyError } from "@oxdeai/guard";
// 1. Initialize the Policy Decision Point (PDP)
const engine = new PolicyEngine({
policy_version: "v1.0.0",
engine_secret: process.env.OXDEAI_ENGINE_SECRET!, // set at deploy time
authorization_ttl_seconds: 60,
authorization_signing_alg: "Ed25519",
authorization_signing_kid: "k1",
authorization_private_key_pem: process.env.OXDEAI_SIGNING_KEY_PEM!, // set at deploy time
authorization_audience: "agent-001",
...RECOMMENDED_TRUSTED_TIME_PROFILE, // required trusted-time bounds
});
// 2. Map the action explicitly: the amount and type the policy evaluates are
// read from the same args the callback executes. Nothing is inferred or
// defaulted. Amounts are fixed-point with 6 decimals: 1 USD = 1_000_000n.
function toIntent(action: ProposedAction): Intent {
const amount = action.args["amount_micros"];
if (action.name !== "charge_wallet" || typeof amount !== "string" || !/^[1-9][0-9]*$/.test(amount)) {
throw new OxDeAINormalizationError("charge_wallet requires a positive integer amount_micros");
}
return { ...defaultNormalizeAction(action), action_type: "PAYMENT", amount: BigInt(amount) };
}
// 3. Create the secure guard. Tenancy posture is explicit, never assumed.
const guard = createSecureGuard(
{
engine,
getState: () => getAgentState(), // returns { state, version }
setState: (s, v) => setAgentState(s, v), // CAS: returns boolean
trustedKeySets: [myKeySet],
expectedAudience: "agent-001", // must match authorization_audience above
mapActionToIntent: toIntent, // explicit amount and type, no estimatedCost default of 0
onDecision: (record) => auditLog(record),
onBoundaryEvent: (event) => auditBoundary(event), // identity/tool conflicts, CAS conflicts
},
{ tenancy: "single-tenant" }
);
// 4. The PEP builds trusted context AFTER authenticating the caller,
// never by trusting a field on the incoming request body.
const trustedContext = createTrustedExecutionContext({
principalId: authenticatedPrincipalId,
agentId: resolveAgentId(authenticatedPrincipalId),
adapterId: "http-pep",
depth: 0, // derived from the real call chain, never proposer-supplied
});
// 5. Validate once, then authorize and execute the same frozen value.
// The action carries no identity claim: identity came from step 4.
const charge = Object.freeze({ wallet_id: walletId, amount_micros: "100000000", currency: "usd" }); // 100.00 USD
try {
await guard(
trustedContext,
{ name: "charge_wallet", args: charge },
async () => chargeWallet(charge) // only runs if ALLOW, with the authorized amount
);
} catch (err) {
if (err instanceof OxDeAIProvenanceConflictError) {
console.error("Trusted-context conflict");
} else if (err instanceof OxDeAIDenyError) {
console.error("Action denied");
} else {
throw err;
}
}
import { verifyAuthorization, createVerifier, verifyEnvelope } from "@oxdeai/core";
// Authorization: strict mode requires trustedKeySets and a verified Ed25519 signature
const result = verifyAuthorization(artifact, {
mode: "strict",
trustedKeySets: [myKeySet],
expectedPolicyId: "policy-production-v1",
});
if (result.status !== "ok" || !result.signatureVerified) {
throw new Error("Authorization not verified"); // fail closed
}
// A valid signature from an unknown issuer → still fails closed
// Missing trustedKeySets in strict mode → TRUSTED_KEYSETS_REQUIRED
// Bound verifier: pre-configure trust once, reuse everywhere
const verifier = createVerifier({
trustedKeySets: [myKeySet], // required, non-empty
expectedIssuer: "oxdeai-pdp",
});
// Envelope: structural checks (snapshot, hash-chained audit, policy id) always run.
// Envelope signatures are optional: strict mode with trustedKeySets alone still
// accepts an UNSIGNED envelope. requireSignatureVerification makes it mandatory.
const envelopeResult = verifyEnvelope(envelopeBytes, {
mode: "strict",
trustedKeySets: [myKeySet],
expectedIssuer: "oxdeai-pdp",
requireSignatureVerification: true, // unsigned → ENVELOPE_SIGNATURE_MISSING
expectedPolicyId: "policy-production-v1",
});
if (envelopeResult.status !== "ok") {
throw new Error("Audit envelope not verified"); // fail closed
}
// With requireSignatureVerification, "ok" means the audit trail is structurally
// intact AND signed by a trusted key for expectedIssuer. Without it, "ok" proves
// structure only.
import { createDelegation } from "@oxdeai/core";
import { createSecureGuard, createTrustedExecutionContext } from "@oxdeai/guard";
// Parent agent ("agent-001", the audience of parentAuth) narrows its authority
// for exactly one child agent. Amounts are fixed-point: 1 USD = 1_000_000n.
const delegation = createDelegation(
parentAuth,
{
delegatee: "child-agent-002", // the only agent this artifact is issued to
scope: {
tools: ["provision_gpu"],
max_amount: 300_000_000n, // 300 USD, strictly narrowed from parent
},
expiry: parentAuth.expiry, // cannot exceed parent
kid: "agent-001-k1", // signed by the parent agent (issuer "agent-001")
},
parentAgentKeyPem // private key passed separately, never inside params
);
// Child-side PEP. DelegationV1 is a signed grant; it does not prove who presents it.
const guard = createSecureGuard(
{
engine, getState, setState,
trustedKeySets: [pdpKeySet, parentAgentKeySet], // parentAuth and delegation signers
expectedAudience: "agent-001", // parentAuth.audience, the delegator
trustedDelegationAuthorities: [ // required: which (issuer, policyId) may root a delegation
{ issuer: "oxdeai.policy-engine", policyId: "policy-production-v1" },
],
mapActionToIntent: toGpuIntent, // explicit amount, as in the guard setup tab
},
{ tenancy: "single-tenant" }
);
// The acting identity comes from authentication, never from the request body.
const childContext = createTrustedExecutionContext({
principalId: authenticatedPrincipalId,
agentId: resolveAgentId(authenticatedPrincipalId), // e.g. "child-agent-002"
adapterId: "http-pep",
depth: 1, // derived from the real call chain
});
// Recipient binding: delegatee must equal the authenticated acting agent.
// On main (#350, not yet published) the guard enforces this itself, before replay
// consumption, state mutation or execution. @oxdeai/guard@2.0.0 does NOT check it,
// so on 2.0.0 this explicit check is required.
if (delegation.delegatee !== childContext.agentId) {
throw new Error("Delegation was not issued to this agent");
}
await guard(
childContext,
{ name: "provision_gpu", args: gpuRequest },
async () => provisionGpu(gpuRequest), // only runs if the chain and scope verify
{
delegation: {
delegation,
parentAuth, // single hop: the parent is an AuthorizationV1, never another delegation
parentScope: { tools: ["provision_gpu"], max_amount: 1_000_000_000n }, // parent's ceiling, from deployer config
},
}
);
// delegation_id and parent auth_id consumed atomically; replay → OxDeAIAuthorizationError
All supported adapters delegate authorization to
@oxdeai/guard and are exercised in CI.
Each adapter ships its own test suite and is validated against
@oxdeai/core in CI before publish.
OxDeAI is open source and Apache-2.0 licensed. Start integrating OxDeAI from source today.