Skip to content

Secure application integration

The SDK enforces finite record semantics. Your host establishes who is acting, which policy applies, what credentials an adapter receives and whether an external report is authentic. Keep that boundary explicit when agents generate applications.

Authenticate before constructing authority

Section titled “Authenticate before constructing authority”

Deny agent attempts to issue new grants · Executable application recipe

import assert from 'node:assert/strict';
import {readFileSync} from 'node:fs';
import {parseContract,type Command} from '@aiws/sdk';
import {SqliteStore} from '@aiws/sdk/sqlite';
import {Coordinator,type Authorizer} from '@aiws/sdk/runtime';
// Demo session comes from the application, never command.context or an event payload.
const session={actor:'agent:builder',isHuman:false};
const humanOnly=new Set(['grant','revokeGrant','approve','withdrawApproval']);
const allowedCommands=new Set(['startRun']); // deliberately narrow teaching policy
const authorize:Authorizer=async(command)=>{
const allowed=allowedCommands.has(command.type)&&(!humanOnly.has(command.type)||session.isHuman);
return {allowed,policy:allowed?'ALLOW':'DENY',mandatoryChecksOk:true,
context:{actor:session.actor,policyRevision:'policy:example:1',decisionClass:'DETERMINISTIC'}};
};
const contract=parseContract(readFileSync('examples/guide/contract.json','utf8'));
const store=new SqliteStore(':memory:',contract);
const coordinator=new Coordinator(store,authorize,()=> '10');
try {
await coordinator.apply({type:'startRun',runId:'r'});
const grant:Command={type:'grant',grant:{id:'g',subject:session.actor,profile:'finite-v1',actions:['write'],resources:['doc'],notBefore:'0',expiresAt:'10000',limit:'100',canDelegate:false,depth:'0'}};
await assert.rejects(coordinator.apply(grant),(e:any)=>e.code==='AUTHORITY_DENIED');
assert.equal(store.snapshot().revision,'1');
assert.equal(store.diagnostics()[0].command.code,'AUTHORITY_DENIED');
} finally {store.close();}

The example uses a fixed trusted-host identity to demonstrate a denial. Replace it with a verified session, service identity or worker capability from your actual identity system. Do not read isHuman, actor, role or ALLOW from an untrusted request body. An approval record represents a decision only after the host has verified who made it and what they approved.

Permission and resource-limit changes for agents always require human approval under the agreed engine design. Enforce this in the authorizer for every relevant operation. A delegated agent must not edit the policy document or identity claims that would allow it to approve its own expansion.

Give each adapter only the filesystem roots, outbound hosts, credentials and tool actions it needs. Validate artifact references and resolved paths before access. For coding tasks, use an isolated checkout or execution environment with explicit command and network policy. A graph node named VERIFICATION does not sandbox the command used to run a test suite.

Treat source files, retrieved documents, webhook payloads, model output and handoff summaries as untrusted input. Embedded instructions cannot change engine policy, grant capabilities or approve new spending. Keep approved intent and machine-readable controls distinct from narrative context.

Bind approval to the exact canonical action fingerprint and valid use count. Reevaluate current policy at dispatch; admission is not a permanent right to act. Avoid logging approval secrets, callback correlation tokens or provider credentials. Verify callback signatures and replay protections in the host before constructing TriggerEvent.

A digest detects changed content under a trusted reference. It does not establish authorship if an attacker can rewrite both the content and digest. Protect the SQLite database, backups, artifact store and audit exports with access controls. Where attestation is required, add a reviewed application signature/provenance mechanism; the SDK does not supply a universal signature protocol.

Enforce limits at ingress before parsing, and limit external response sizes and adapter execution time. Choose conservative reservations before dispatch. Monitor the journal and telemetry outbox: disk-backed storage is not an unlimited queue. Do not release an UNKNOWN reservation just to let a new request proceed.

Use secret references in configuration and resolve credentials at execution. Rotate credentials independently of durable workflow history. If a credential expires while a workflow is paused, reauthenticate and reauthorize at continuation rather than relying on a saved token.

For suspected tampering or an uncertain side effect, block affected work, preserve IDs and receipts, and route a specific decision to an authorized human. Do not delete history, fabricate verification or automatically broaden permissions as a repair strategy. See recovery and handoffs for the durable record needed to resume safely.