Sign inSign up

vengtoo/agent

By vengtoo

•Updated 2 months ago

Lightweight authorization sidecar for AI agents, APIs and microservices.

Image
Security
Machine learning & AI
Developer tools
0

1.8K

vengtoo/agent repository overview

⁠Vengtoo Agent

License Go Docker

Lightweight authorization sidecar for AI agents, APIs, and microservices.

Open-source. Self-hostable. No vendor lock-in.

The Vengtoo Agent runs alongside your services and makes authorization decisions locally with sub-millisecond latency. It pulls policies from Vengtoo Cloud (or loads them from a local file), evaluates requests against the authorization engine in-memory, and returns allow/deny decisions without network round-trips on the hot path.

Policies are written in Vengtoo's native YAML/JSON format: declarative allow/deny rules with roles, attribute conditions, time windows, IP allowlists, MFA checks, and trust levels, no policy language to learn. Already running OPA? The agent also accepts Rego files as a drop-in in local mode, so you can point it at an existing policy fleet and try it in minutes.

⁠What it does

  • Serves POST /access/v1/evaluation with sub-millisecond decision latency, no per-request calls to the cloud
  • Syncs policy bundles automatically from Vengtoo Cloud: pushed instantly over a change stream, with a poll fallback (configurable interval)
  • Keeps serving decisions from the last good bundle if the cloud becomes unreachable (reported via /healthz as degraded)
  • Verifies Ed25519 bundle signatures against pinned keys, so a compromised distribution channel can't inject policy
  • Exposes Prometheus metrics, structured decision logs, and health endpoints out of the box

⁠Benchmarks

Verify this yourself:

go run ./cmd/benchmark
go run ./cmd/benchmark -policies 10000 -roles 200 -subjects 20000 -iterations 50000

cmd/benchmark generates a synthetic policy bundle (mixed direct/role assignments, ABAC conditions, occasional DENY overrides; see cmd/benchmark/bundle.go for exact proportions, which are a documented assumption, not customer data) and measures YAMLEngine.Evaluate(), the exact code path that serves every /access/v1/evaluation request in default (cloud-synced) mode. No network calls, no OPA/Rego involved (Rego is only used by the separate --policy standalone mode, for pointing the agent at your own existing .rego files).

Representative results on a normal development laptop:

Bundlep50p95p99
300 policies / 500 subjects0.6µs1.0µs2.4µs
2,000 policies / 5,000 subjects1.3µs2.3µs4.0µs
10,000 policies / 20,000 subjects1.5µs2.4µs3.0µs

p95 stays in single-digit microseconds even at 10,000 policies: evaluation is O(subject assignments), not O(all policies), so it doesn't degrade with bundle size the way a linear policy scan would. -policies/-roles/-subjects/-iterations are all flags; vary them and see how it holds up on your own hardware and bundle shape, not just ours.

⁠Quick Start

⁠Install

Docker (recommended): vengtoo/agent⁠ on Docker Hub.

docker pull vengtoo/agent:latest

Go install:

go install github.com/vengtoo/agent/cmd/agent@latest

Binary download:

Grab the latest release from GitHub Releases⁠ for your platform (linux/amd64, linux/arm64, darwin/arm64).

⁠Configure

Create vengtoo-agent.yaml (or set environment variables):

api_key: "your-vengtoo-api-key"
cloud_url: "https://api.vengtoo.com"
listen_addr: "0.0.0.0:8181"
poll_interval: "30s"
⁠Run
# With config file
vengtoo-agent --config ./vengtoo-agent.yaml

# With env vars
VENGTOO_API_KEY=your-key vengtoo-agent

# With Docker
docker run -d \
  -e VENGTOO_API_KEY=your-key \
  -p 8181:8181 \
  -v vengtoo-cache:/var/lib/vengtoo/bundles \
  vengtoo/agent:latest
⁠Test with curl
# Allowed request
curl -s -X POST http://localhost:8181/access/v1/evaluation \
  -H "Content-Type: application/json" \
  -d '{
    "subject": { "type": "agent", "id": "ai-assistant" },
    "resource": { "type": "mcp_tool", "name": "database__query" },
    "action": { "name": "invoke" }
  }'
{
  "allowed": true,
  "reason": "Access granted via role",
  "access_path": "role"
}
# Denied request — AI agent tries to drop a table
curl -s -X POST http://localhost:8181/access/v1/evaluation \
  -H "Content-Type: application/json" \
  -d '{
    "subject": { "type": "agent", "id": "ai-assistant" },
    "resource": { "type": "mcp_tool", "name": "database__execute", "attributes": { "sql": "DROP TABLE users" } },
    "action": { "name": "invoke" }
  }'
{
  "allowed": false,
  "reason": "BLOCKED: DROP operations are not permitted for AI agents"
}

⁠Configuration

The agent loads config from YAML (--config <path>, ./vengtoo-agent.yaml, or ~/.vengtoo/agent.yaml). Environment variables override YAML values.

Env varYAML keyDefaultDescription
VENGTOO_API_KEYapi_key- (required for cloud mode)API key from Vengtoo Cloud⁠
VENGTOO_CLIENT_SECRETclient_secret-When set, requires Authorization: Bearer <secret> on /access/v1/evaluation.
VENGTOO_CLOUD_URLcloud_urlhttps://api.vengtoo.comVengtoo Cloud base URL
VENGTOO_TENANT_IDtenant_id(auto-resolved)Tenant ID; auto-detected from bundle if not set
VENGTOO_LISTEN_ADDRlisten_addr0.0.0.0:8181HTTP listen address
VENGTOO_POLL_INTERVALpoll_interval30sHow often to sync policies from the cloud
VENGTOO_CACHE_DIRcache_dir~/.vengtoo/bundlesDirectory for persisted policy bundles
VENGTOO_LOG_LEVELlog_levelinfoLog verbosity (debug, info, warn, error)
VENGTOO_DECISION_LOGdecision_logfalseEnable structured JSON decision logging to stdout
VENGTOO_AGENT_NAMEagent_namehostnameIdentifies this agent instance in the dashboard
VENGTOO_AGENT_REGIONagent_region-Display label for the region this agent runs in
VENGTOO_AGENT_DOMAINagent_domain-Display label for the domain or environment
VENGTOO_HEARTBEAT_INTERVALheartbeat_interval30sHow often the agent sends a liveness ping to cloud
VENGTOO_AUDIT_FORWARDINGaudit_forwardingtrueForward decisions to cloud Decision Log
VENGTOO_AUDIT_ENDPOINTaudit_endpointderived from cloud_urlOverride the audit ingest endpoint
VENGTOO_AUDIT_BATCH_SIZEaudit_batch_size100Decision events to buffer before flushing
VENGTOO_AUDIT_BATCH_INTERVALaudit_batch_interval5sMaximum wait before flushing a partial batch
VENGTOO_AUDIT_BUFFER_SIZEaudit_buffer_size10000In-memory buffer capacity for decision events
VENGTOO_AUDIT_RETRY_ATTEMPTSaudit_retry_attempts5Retry attempts for failed audit log flushes
VENGTOO_TRUSTED_KEYS_PATHtrusted_keys_path~/.vengtoo/trusted_keys.jsonPinned public keys for bundle signature verification
VENGTOO_BUNDLE_SIGNATURE_REQUIREDbundle_signature_requiredfalseReject unsigned bundles; set true for strict verification
VENGTOO_AGENT_HOSTINGagent_hostingselfHosting label shown in the dashboard (self, aws, gcp, etc.)

⁠Modes

⁠Cloud mode (default)

The agent connects to Vengtoo Cloud, pulls your tenant's native policy bundle, and keeps it fresh two ways: an SSE change stream pushes updates the moment a policy changes, and a poll fallback (default 30s) covers dropped streams. This is the standard production deployment. Cloud mode always uses the native engine; Rego is not involved.

VENGTOO_API_KEY=your-key vengtoo-agent

Note: cloud-mode requests address subjects and resources by their canonical IDs. If the initial bundle fetch fails at startup the agent exits; it does not yet cache bundles to disk across restarts (planned).

⁠Local mode

Load policies from a local file instead of the cloud. No API key or cloud account required. Two formats are supported:

Native YAML/JSON (recommended): Vengtoo's own policy format, same semantics as cloud mode:

vengtoo-agent --policy ./authz.yaml

# Two-file mode: rules in YAML, assignments/role members in JSON data
vengtoo-agent --policy ./authz.yaml --data ./data.json
# authz.yaml
policies:
  - id: eng-can-read-docs
    effect: ALLOW
    actions: [read]
    resource_type: document
    conditions:
      subject_attrs:
        - {key: dept, op: eq, value: engineering}
      mfa_required: {}
    assignments:
      - {entity_type: role, entity_id: engineers}
roles:
  - id: engineers
    members:
      - {entity_type: entity, entity_id: alice}

Conditions support eq/ne/gt/gte/lt/lte/in/not_in/matches attribute checks on subject, resource, and context, plus time_window, ip_allowlist, mfa_required, trust_level, and custom Go condition functions. Malformed condition keys fail closed: the policy is kept but never matches, and a warning names the policy and the offending key at load time.

OPA Rego (drop-in compatibility): point the agent at an existing .rego policy fleet and it behaves as a local OPA engine. Useful for trying the agent as an OPA replacement without rewriting anything:

# Single file
vengtoo-agent --policy ./examples/policy.rego

# Directory of .rego files (loaded as separate OPA modules)
vengtoo-agent --policy ./policies/

# With external data (roles, groups, permissions, etc.)
vengtoo-agent --policy ./policies/ --data ./data/

# With a non-standard decision rule name
vengtoo-agent --policy ./policies/ --decision permit

Rego is supported in local mode only; cloud bundles are always native. If you're starting fresh, use the native format.

FlagDefaultDescription
--policy <path>-Path to a native .yaml/.yml/.json policy file, a .rego file, or a directory of .rego files
--data <path>-Native: JSON file with assignments/role_members. Rego: JSON file(s) loaded as OPA data (data.*)
--decision <rule>allowRego only: OPA rule name for the allow/deny result (e.g. permit, authorized)
--addr <addr>0.0.0.0:8181HTTP listen address

See examples/policy.rego⁠ for a starter Rego policy.

Local mode is useful for:

  • Self-hosted deployments without cloud dependency
  • Dropping in an existing OPA policy fleet with no changes
  • CI/CD pipeline testing
  • Policy authoring and iteration
⁠Writing a local Rego policy

The agent passes the following input shape to OPA:

{
  "subject":   { "id": "...", "type": "...", "attributes": {}, "roles": [] },
  "resource":  { "id": "...", "type": "...", "name": "...", "attributes": {} },
  "action":    { "name": "invoke" },
  "context":   { "time": "2026-06-27T10:00:00Z" }
}

input.action is an object: use input.action.name to get the action string. This matches standard OPA convention so existing policies work without modification.

The agent auto-detects the package from your Rego file. Use any package name you like:

package myapp        # query path: data.myapp.allow
package authz        # query path: data.authz.allow
package vengtoo.mcp  # query path: data.vengtoo.mcp.allow

Your policy must define allow (bool). Optionally define reason (string) for a human-readable deny message returned in the response.

⁠Health and Observability

⁠Endpoints
EndpointPurpose
POST /access/v1/evaluationSingle authorization check. Returns { allowed, reason, access_path }.
POST /access/v1/evaluationsBatch authorization: evaluate multiple subject/resource/action tuples in one request.
GET /.well-known/authzen-configurationAuthZEN 1.0 discovery endpoint.
GET /healthzLiveness check. Returns 200 while the process is running. Includes bundle revision, sync age, and degraded status.
GET /readyzReadiness check. Returns 200 once a policy bundle is loaded (from cache or cloud). Returns 503 until ready.
GET /metricsPrometheus metrics (decisions total, latency histogram, sync status, degraded state).
⁠Decision logging

Enable structured decision logs for auditing and debugging:

VENGTOO_DECISION_LOG=true vengtoo-agent

Each /access/v1/evaluation call emits a JSON log line:

{
  "time": "2026-04-19T14:03:11.482Z",
  "level": "INFO",
  "msg": "decision",
  "subject_id": "user-123",
  "resource_id": "doc-456",
  "action": "view",
  "decision": true,
  "reason": "Access granted via role",
  "access_path": "role",
  "ms": 0.42
}
⁠Key metrics
MetricTypeDescription
vengtoo_agent_decisions_totalcounterTotal authorization decisions (by allowed, access_path)
vengtoo_agent_decision_duration_secondshistogramEvaluation latency
vengtoo_agent_degradedgauge1 when serving from stale cache
vengtoo_agent_bundle_last_sync_timestamp_secondsgaugeUnix timestamp of last successful sync

⁠MCP Gateway

Using AI agents with MCP (Claude Code, Cursor, VS Code, GitHub Copilot)? The Vengtoo MCP Gateway⁠ sits in front of your MCP servers and uses the Vengtoo Agent to authorize every tool call before it executes.

⁠Feedback

⁠License

Apache-2.0, see LICENSE⁠.

Tag summary

Content type

Image

Digest

sha256:456a4b9a9…

Size

18.3 MB

Last updated

2 months ago

docker pull vengtoo/agent