Principal
Agent::"research"Who is asking? A user or an agent.
AgentGuard evaluates proposed tool calls against Cedar policies before your application executes them. Separate intent from permission, and keep a record of the decision.
Principal, action, resource, and MFA match.
A model can choose an action. Your application still needs to decide whether that principal may perform it on that resource, in this context.
Access follows whatever credentials the tool happens to hold.
Your adapter asks for a decision and executes only on allow.
Agent::"research"Who is asking? A user or an agent.
Action::"ToolCall::repo_read"What operation is being proposed?
Repository::"demo"Which object will the tool touch?
session.mfa: trueWhich trusted facts apply now?
The HTTP path joins policy evaluation, configured audit logging, and response handling. Your application supplies identity and owns tool execution.
Your adapter catches the proposed tool call before execution.
Authenticate the caller and derive the acting principal in trusted application code.
Map principal, action, resource, context, and required entities.
The Cedar authorizer returns allow or deny with policy diagnostics.
The configured server audit log receives the decision before it is returned.
The PDP responds to the adapter. Errors are not permission.
Your adapter executes only on an explicit allow.
Inspect decision metrics and trace context; connect telemetry sinks where needed.
The embedded engine returns a decision without automatically writing an audit record. The CLI logs by default unless audit is skipped. Step-up is represented in SDK response handling; the current Cedar/server decision path returns allow or deny.
Cedar gives authorization a dedicated language: explicit principals, actions, resources, and conditions. Its Rust engine and typed schema keep policy separate from your tool implementation.
No matching permit means deny. A matching forbid takes precedence.
Keep rules in .agentguard/policies/ and run agentguard validate against schema.cedarschema.
Rust library APIs provide versioned bundles, line diffs, and replay-based blast-radius analysis. Rollback requires restoring a prior bundle and reloading the authorizer.
permit (
principal == Agent::"research",
action == Action::"ToolCall::repo_read",
resource == Repository::"demo"
) when {
context.session has mfa &&
context.session.mfa
};Replace both generated starter policies for this example. The standalone watcher atomically reloads a complete policy snapshot after successful parsing; malformed edits retain the last known-good snapshot.
With a chain secret configured, each audit record links to the previous record using HMAC-SHA256. Verify the chain when investigating a decision or exporting evidence.
Without a secret, the log is plain JSONL. Protect the secret and preserve an independent trusted checkpoint to detect log replacement or tail truncation.
agentguard audit verify --secret-file .chain-secret
agentguard audit export --format ecs --out decisions.ecs.jsonlresearch · repo_read · demo
7e2…a61…sample · 12:00:00Zsummarizer · repo_read · demo
a61…b03…sample · 12:00:01Zresearch · repo_read · demo
b03…c92…sample · 12:00:02ZIllustration only. Use the CLI for cryptographic verification.
Agent::"research"Application checks the parent’s authority.
Agent::"summarizer"Action: ToolCall::repo_read
Resource: Repository::demo
TTL: 300 seconds
Mint signed tokens with action scopes, resource patterns, and expiry. Verify signatures, audience, and time claims with the Rust verifier.
Your integration must enforce those scopes and ensure the parent may delegate them. DPoP is a separate verifier library. The standalone PDP does not automatically consume delegation tokens, and there is no delegation revocation endpoint.
Understand delegation responsibilities →Authentication and authorization are separate steps. Map trusted identity into a Cedar principal before submitting a decision request.
JWT / OIDC · API keys
SPIFFE workload identity
Your application validates identity and resolves the acting subject.
User::"alice" or
Agent::"research"
Standalone PDP: API-key authentication or local disabled mode. Console: OIDC sign-in with viewer/admin roles. Rust libraries: JWT, OIDC discovery, DPoP verification, and feature-gated SPIFFE/SPIRE Workload API access. These are distinct integration surfaces.
Identity methods and trust boundaries →Expand a component to inspect its role and integration boundary. Requests flow toward the engine; decisions return to the enforcement point.
Calls the PDP before execution and honors deny and transport failures.
typescript/agentguard spawns the local binary synchronously.
agentguard-cli handles local authorization, simulation, audit, and token operations.
frontend uses HTTP for simulation and the CLI for audit and delegation.
agentguard-server maps requests to the core authorizer. API-key middleware protects decision routes.
agentguard-core evaluates loaded policies against a typed request and supplied entities.
Use Authorizer directly in-process, or build_router to embed the HTTP surface.
LRU + TTL cache in core. Standalone startup enables it with environment overrides; embedders enable it explicitly.
.agentguard/schema.cedarschema and policies/*.cedar are local files.
agentguard-auth provides validation libraries; the application binds identity to a principal.
Configured server logging persists decisions; a chain secret enables HMAC-linked records.
Server Prometheus metrics and trace context; library sinks for stdout, JSONL, and optional OTLP.
Use the Rust authorizer in your application when you own the process and security lifecycle.
Keep the standalone PDP beside your agent runtime. Use a local HTTP or gRPC boundary.
Centralize HTTP decisions for multiple callers. Configure authentication, TLS, and durable audit storage.
Use the same request model through your preferred interface. These examples follow the repository’s current APIs; the quickstart supplies their policy and request data.
import { Client, Principal, Action } from "agentguard";
const guard = new Client({ store: ".agentguard" });
guard.check(
Principal.agent("research"),
Action.tool("repo_read"),
{ entity_type: "Repository", uid: "demo", attrs: { org: "example" } },
{ args: { repo: "demo" }, session: { mfa: true } },
);
// Permission granted. Your application may now run the tool.
// On denial, check() throws AuthorizationDenied.Node.js SDK. Spawns the installed CLI synchronously. Call your tool only after check() returns.
curl --fail-with-body http://127.0.0.1:8443/access/v1/evaluation \
-H 'Content-Type: application/json' \
-d '{
"subject": {
"type": "Agent",
"id": "research"
},
"action": {
"type": "Action",
"id": "ToolCall::repo_read"
},
"resource": {
"type": "Repository",
"id": "demo"
},
"context": {
"args": {
"repo": "demo"
},
"session": {
"mfa": true
}
}
}'
# Proceed only if the response succeeds and decision === true.For the loopback quickstart. Remote deployments need transport protection and authenticated access.
agentguard validate
agentguard --output json authorize request.json
agentguard sim request.json
agentguard log tail --n 10
agentguard doctorrequest.json is the CLI request from the quickstart. Exit code 2 means deny; other failures must also stop execution.
use agentguard_core::{AgentRequest, Authorizer, PolicyStore};
use cedar_policy::Entities;
let store = PolicyStore::open(".agentguard")?;
let authorizer = Authorizer::new(store)?;
let req: AgentRequest = serde_json::from_str(request_json)?;
// This policy uses IDs and context, not entity attributes.
let entities = Entities::empty();
let decision = authorizer.authorize(&req, &entities)?;
// Check decision.effect before executing the tool.
// Append to your configured DecisionLog at this boundary.Inside a function returning Result. The embedded engine returns a decision; your application owns enforcement, identity, and audit wiring.
import { AgentGuard, guarded } from "./guard.js";
const guard = new AgentGuard({
principal: { type: "Agent", id: "research" },
resource: { type: "Repository", id: "demo" },
});
// Wrap your tool config before registering it with Strands:
const protectedTool = guarded(guard, toolConfig);
// The callback runs only after an explicit HTTP allow.
// Tailor the schema and policy to toolConfig's input.The guarded() helper belongs to examples/strands-tool-authz. It is an example adapter, not an exported SDK method.
An HTTP guard wraps tool execution. Transport errors and missing permission stop the callback. Includes a BeforeToolCallEvent intervention example.
Explore the Strands example ↗Mount AgentGuard’s HTTP router in an existing Rust application. Review the nesting path and configure audit and authentication for your deployment.
Explore the Rust example ↗AuthZEN-compatible clients can call the HTTP interface. Custom frameworks, LangChain loops, and MCP tool servers can integrate through their own enforcement adapter. This is interoperability, not a claim of official adapters for those projects.
Support is specific to a component and interface. Library primitives are not automatically enabled server features, and compatibility is not certification.
The Rust engine evaluates typed authorization requests.
Inspect implementation ↗HTTP single and batch evaluation; a repository-defined gRPC mirror.
Inspect implementation ↗HTTP traceparent input and child span identifiers.
Inspect implementation ↗Library checks signatures, issuer, audience, and time claims.
Inspect implementation ↗OIDC library metadata discovery with issuer validation.
Inspect implementation ↗DPoP verifier library checks binding, signature, method, URI, and replay.
Inspect implementation ↗Feature-gated Workload API client with trust-domain validation.
Inspect implementation ↗Actor and audience claims are building blocks; no token-exchange endpoint or resource-parameter API is exposed.
Inspect implementation ↗The server accepts W3C traceparent and returns x-agentguard-span-id. Prometheus metrics expose authorization activity; audit records preserve decision evidence.
The telemetry crate provides a Sink interface and an optional OTLP/gRPC log exporter. Connect it in your embedding application; setting an endpoint alone does not enable export in the standalone server.
Metrics, trace fields, and sink wiring →Change a request and inspect the result. This browser simulation checks the four conditions below in JavaScript. It does not execute Cedar, contact a server, or create an audit record.
permit (
principal == Agent::"research",
action == Action::"ToolCall::repo_read",
resource == Repository::"demo"
) when {
context.session has mfa &&
context.session.mfa
};All permit conditions match. The adapter may execute the tool.
{
"subject": {
"type": "Agent",
"id": "research"
},
"action": {
"type": "Action",
"id": "ToolCall::repo_read"
},
"resource": {
"type": "Repository",
"id": "demo"
},
"context": {
"args": {
"repo": "demo"
},
"session": {
"mfa": true
}
}
}Illustrative fields only. No signature or chain is generated here.
{
"effect": "allow",
"principal": "research",
"action": "repo_read",
"resource": "demo",
"policies": [
"example-permit"
],
"timestamp": "illustrative timestamp"
}The Next.js console offers audit browsing with filters, an HTTP-backed authorization simulator, and admin-only delegation issuing and verification.
OIDC sign-in is mandatory. Viewer/admin roles gate access, and missing authentication configuration returns 503. The console is a separate application you run in your infrastructure.
Configure and run the console ↗Start locally with Rust 1.89+ and protoc for the server build. The guide walks from the generated schema to a narrow permit, a real allow/deny pair, an HTTP request, and audit verification.
The CLI includes init, validate, authorize, sim, delegate, verify, schema, log, audit, gen, and doctor. The server has its own binary; policy operations are Rust library APIs.
Follow the complete quickstart →git clone https://github.com/sachncs/agent-guard.git
cd agent-guard
cargo install --path crates/agentguard-cli
cargo install --path crates/agentguard-serverBuild locally from source. These buttons display commands; they do not execute them.
Local files define policies and audit storage. Server flags, library options, and console settings have different scopes.
AGENTGUARD_LISTENLoopback HTTP by default. TLS listener for protected remote access.
AGENTGUARD_STOREThe standalone server watches policy and schema files, then atomically reloads valid snapshots. Invalid changes retain the last known-good policy.
AGENTGUARD_CHAIN_SECRETPath to the HMAC secret. Required for a chained log.
--auth apikeyStandalone API-key mode; console OIDC is configured separately.
Authorizer::with_cacheStandalone cache defaults to 10k entries / 60s allows / 5s denies; embedders use Authorizer::with_cache.
OTEL_EXPORTER_OTLP_ENDPOINTUsed when constructing the optional OTLP library sink.
AGENTGUARD_GRPC_LISTENOptional plaintext listener, restricted to loopback.
AGENTGUARD_TRACEPARENTCLI trace context; HTTP clients use the traceparent header.
A clear boundary is more useful than a broad security promise. Authorization is one control in your application’s security model.
Six Rust crates, a TypeScript SDK, an optional console, and working integration examples. Inspect the implementation behind each interface.
agentguard-core ↗Cedar, entities, audit, cache, delegationagentguard-server ↗HTTP and gRPC decision interfacesagentguard-cli ↗Local policy and audit commandsagentguard-auth ↗Identity validation primitivesagentguard-policy ↗Bundles, diff, replay analysis, watcheragentguard-telemetry ↗Metrics and pluggable event sinkstypescript/agentguard ↗Node.js CLI-backed SDKfrontend ↗Optional OIDC-protected consoleexamples ↗Strands and Rust router examplesschemas ↗Starter Cedar schemasite ↗This static Astro product siteCedar authorization, HTTP/gRPC, audit export, TypeScript SDK, and the OIDC console. The shipped boundaries, compatibility notes, and current limitations are documented in the repository and versioned guides.
Docker and Kubernetes manifests provide non-root images, health probes, resource limits, secret references, persistent audit storage, and explicit single-replica scaling limits for the current release.
Contributor setup, security response, compatibility policy, release checks, and API references are maintained alongside the implementation.
Start with the boundary, then choose the integration and operating model that fit your application.
No. It is Apache-2.0 software you deploy and operate. The public website has no hosted authorization backend.
It constrains the actions a policy allows at an enforced tool boundary. It does not detect every malicious prompt, inspect model reasoning, or protect an unguarded execution path.
Cedar denies by default. An applicable permit is required; an applicable forbid overrides permits. Replace broad generated starter policies before deployment.
Yes, through an adapter that calls the HTTP PDP, CLI, or embedded Rust engine before execution. Strands has a repository example; other frameworks require integration work.
Immediately before a tool executes, using the actual target and arguments. Guard every relevant execution path, including retries and delegated calls.
The standalone server can run beside your application or as a shared PDP. Rust applications can use Authorizer in-process or mount build_router. Embedders own lifecycle and security configuration.
Configure a chain secret to enable HMAC-SHA256 linked records. Protect the key, retain trusted chain checkpoints, and verify logs offline; a chain alone does not prove completeness.
The CLI and Rust primitives mint scoped, time-limited Ed25519 JWS tokens. Applications must verify tokens and enforce their action/resource scopes alongside Cedar.
Stop execution. The Strands guard fails closed on transport errors and non-allow results. Custom adapters must implement the same behavior.
Derive identity, MFA, ownership, and environment from trusted systems. API keys are bound to one User or Agent subject and the PDP rejects requests that claim a different subject. Tenant metadata is not automatically a Cedar policy attribute; encode tenant isolation explicitly in trusted entities and policies.