@gomagentic/verdict-dsl
v0.1.1
Published
Verdict policy language (VPL) lexer, parser, and compiler to VIR. Also compiles the JSON policy form.
Downloads
302
Maintainers
Readme
@gomagentic/verdict-dsl
The Verdict policy language (VPL): parse and compile policies to VIR bytecode.
Part of Verdict — a serverless-first authorization engine. Policies (RBAC / ABAC / ReBAC) compile once and decide in microseconds, embedded in your app, behind a central PDP, or synced to the edge.
This package is the compiler front end. It lexes and parses VPL source (or the isomorphic JSON policy form), performs semantic analysis, folds constants, and emits a compact VIR program — the bytecode @gomagentic/verdict-engine evaluates. Parsing and compilation are the cold path: they run at publish time, never inside a decision.
Install
npm install @gomagentic/verdict-dslCompile a policy
Author a policy in VPL, then compile and seal it into a content-hashed bundle:
import { compileOrThrow, sealBundle } from "@gomagentic/verdict-dsl";
const source = `
version "v1"
constants {
MAX_SELF_APPROVE_DAYS = 2
}
variables {
is_owner = user.id == resource.attr.ownerId
}
resource "leave" {
deny "block-suspended" {
actions = ["*"]
condition = user.attr.suspended == true
}
allow "owner-manages-own" {
roles = ["employee"]
actions = ["view", "update"]
condition = is_owner
}
}
`;
// compileOrThrow(files): { program, warnings } — throws a VerdictError
// (ErrorCode.PolicyInvalid) carrying every diagnostic when compilation fails.
const { program, warnings } = compileOrThrow([
{ path: "leave.vpl", source, format: "vpl" },
]);
for (const w of warnings) console.warn(w);
// sealBundle(program, opts): Promise<BundleEnvelope> — wraps the program in a
// content-hashed, tenant-scoped envelope ready for the engine.
const bundle = await sealBundle(program, { tenantId: "acme", bundleVersion: 1 });Feed the sealed bundle straight to the evaluator:
import { Verdict } from "@gomagentic/verdict-engine";
const verdict = await Verdict.fromBundle(bundle); // µs decisions, zero networkNeed the raw compiler instead of the sealing helpers? compilePolicySet(files) returns { program?, diagnostics } without throwing — program is undefined when any diagnostic has severity "error". A CompileFile is { path, source, format }, where source is VPL text (format: "vpl") or a PolicyDocument object / JSON string (format: "json").
JSON policy form
VPL, JSON, and YAML are isomorphic — they compile to identical VIR, and conditions are VPL expression strings in every form. documentToFileAst(doc, path) normalizes a PolicyDocument (the verdict/v1 JSON shape) into the same FileAst the VPL parser produces, so one compiler backend serves both. You rarely call it directly: pass { format: "json", source } to compilePolicySet / compileOrThrow and the compiler invokes it for you. YAML callers parse to an object with any YAML library first, then hand the result in as JSON.
const { program } = compileOrThrow([
{
path: "leave.json",
format: "json",
source: {
apiVersion: "verdict/v1",
kind: "ResourcePolicy",
metadata: { name: "leave", version: "v1" },
spec: {
variables: { same_dept: "user.attr.department == resource.attr.department" },
rules: [
{
name: "manager-approves-reports",
effect: "allow",
actions: ["approve", "reject"],
condition: "user.id == resource.attr.managerId && same_dept",
},
],
},
},
},
]);Diagnostics
Every diagnostic is a Diagnostic — { severity, message, file, line, col } — and carries a SourcePos back to the offending VPL token. compilePolicySet collects them all rather than failing fast; compileOrThrow throws when any is an error. formatDiagnostic(d) renders one as file:line:col severity: message. ParseError is the internal signal for an unrecoverable parse failure — it is converted to a Diagnostic at the compile-unit boundary and never leaks to callers of the public API.
Key exports
| Export | Purpose |
|---|---|
| lex, TokenKind, Token | Tokenize VPL source (MAX_SOURCE_BYTES cap). |
| parseVpl, parseExpr | Parse a full file, or a single condition expression (MAX_EXPR_DEPTH limit). |
| documentToFileAst | Normalize the JSON PolicyDocument form into a FileAst. |
| compilePolicySet | Compile a set of files to { program?, diagnostics } — never throws. |
| compileOrThrow | Compile, or throw a VerdictError with all diagnostics; returns { program, warnings }. |
| sealBundle | Wrap a VirProgram in a content-hashed BundleEnvelope. |
| COMPILER_VERSION | Compiler version stamped into every emitted program. |
| COMPILE_LIMITS | Spec limits enforced at compile time (instructions, rules, policies). |
| formatDiagnostic, ParseError, Diagnostic, SourcePos | Diagnostics and source positions. |
The full AST node types (from ast.js) are re-exported for tools that inspect or transform parsed policies.
Documentation
License
Apache-2.0
