Skip to content

Latest commit

 

History

993 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

GrantLayer

PostgreSQL CI Coverage Python License

GrantLayer is access-grant and authorization infrastructure: an open-source, multi-tenant system for issuing time-boxed access grants to AI agents and automated systems, enforcing them through a policy engine, and recording every decision in a cryptographically verifiable audit trail. A grant is a permission — who may perform which action on which resource, for how long — and every issue, approval, denial, revocation, and exercise is traceable, tamper-evident, and independently auditable. It is in Developer Preview — local evaluation and controlled pilot only. It is not production SaaS; production SaaS readiness is not claimed. No GitHub push and no repository visibility change are part of this local quickstart.


Status

Area Status
Production SaaS readiness Not claimed
Tenant/workspace isolation Enforced at API level — workspace-scoped queries, cross-workspace denial
Public GitHub release Available
Real customer data in examples None; examples use synthetic/demo data only
Real secrets in examples None; use placeholders or generated local values only

Production SaaS readiness is not claimed. Tenant/workspace isolation is enforced at the API level: every request resolves a workspace_id and tenant_id from the operator identity; queries are server-side scoped to that workspace and tenant; cross-workspace access is denied by default. This provides strong isolation for developer preview and controlled pilot deployments. Examples use no real secrets and no real customer data.


Quickstart

Choose your path

  • Path A: run the first verifiable output quickstart below. It requires no backend and uses Python stdlib only.
  • Path B: run the backend quickstart with Docker Compose or local Python setup.

Get the stack running in under 5 minutes:

git clone https://github.com/Discodone/grantlayer.git
cd grantlayer
cp .env.example .env          # local-eval defaults boot as-is (JWT keys for API calls: QUICKSTART.md step 1)
./nginx/generate-certs.sh     # self-signed TLS for local dev

# Provision the schema with Alembic. PostgreSQL is the default backend and the
# app does not self-provision it — skip this and the API fails to start.
docker compose up -d db
docker compose run --rm api python3 -m alembic -c backend/alembic.ini upgrade head

docker compose up -d
curl -k https://localhost/health

See QUICKSTART.md for the full walkthrough: token generation, creating grants, grant requests, and audit log export.

The stack defaults to GRANTLAYER_RUNTIME_MODE=local for evaluation; set production in .env to enable the hardened production gates (see DEPLOYMENT.md). The Cardano anchoring worker is optional and starts only with docker compose --profile anchoring up -d after creating the secrets files described in secrets/README.md — the default stack requires neither.

See CHANGELOG.md for public snapshot version anchors and caveats.

First Verifiable Output Quickstart

Run the first verifiable output quickstart:

python3 examples/first_verifiable_output.py --output /tmp/grantlayer_first_output.json

The generated file is /tmp/grantlayer_first_output.json. The committed deterministic reference output is examples/first_verifiable_output.json; see docs/first_verifiable_output.md.

This path is local/demo only, requires no real secrets, requires no customer data, uses no real secrets, and uses no real customer data.


API Overview

Method Path Description
GET /health Liveness check
GET /v1/grants List all grants
POST /v1/grants Create a grant
POST /v1/grants/:id/revoke Revoke a grant
GET /v1/grant-requests List grant requests
POST /v1/grant-requests Submit a grant request (requires GRANTLAYER_ENABLE_OPERATOR_MODEL=true)
POST /v1/grant-requests/:id/approve Approve a grant request
POST /v1/grant-requests/:id/deny Deny a grant request
POST /v1/exercise Exercise a grant — records the policy-checked decision as an audit event (/v1/demo-action is a legacy alias that 307-redirects here)
GET /v1/audit-events List audit events
GET /v1/grant-executions List grant executions (owner/v1/admin/v1/auditor)

Full OpenAPI spec: docs/openapi.yaml. Interactive Swagger UI available at /api/docs when the stack is running.


Architecture

GrantLayer is a Python/FastAPI backend served behind an Nginx TLS reverse proxy. Storage is PostgreSQL 16 in the Docker Compose stack (the compose default) or SQLite when running bare locally with GRANTLAYER_DATABASE_URL unset. All grants are signed with Ed25519 and form a tamper-evident audit chain — each event records what was decided, by whom, and when. The operator model provides a request/approval workflow: subjects submit grant requests, and operators approve or deny them. JWT authentication guards all API endpoints — RS256 by default (base64-PEM keypair via GRANTLAYER_JWT_PRIVATE_KEY/GRANTLAYER_JWT_PUBLIC_KEY), with legacy HS256 when only GRANTLAYER_JWT_SECRET is set; tokens encode the caller's subject, tenant, role, and expiry. Docker Compose brings up the API, Nginx, and PostgreSQL as a single docker compose up command.

Audit-chain scope — the un-anchored window. The optional on-chain anchoring commits to the audit chain only as it stood when an anchor was published. Events appended after the newest anchor sit in an un-anchored window: the row-hash chain alone cannot expose a database-level rewrite of that window (truncating to an earlier prefix, re-linking the chain after an edit, or mutating a field and re-hashing in place all yield a chain that still verifies), and no on-chain commitment covers those events until the next anchor is published. Anchors are deliberately cadence-free — each is an explicit operator act, not a scheduled job — so the window has no fixed length. This is the structural trade-off of periodic anchoring, not a defect: an anchor bounds what the past can be rewritten to, it does not protect what has not yet been anchored.


Configuration

Variable Default Description
GRANTLAYER_RUNTIME_MODE local (Docker Compose) / production (when unset) Runtime mode. Valid values: local, demo, test, staging, production
GRANTLAYER_JWT_SECRET (unset) Shared secret enabling legacy HS256 JWTs; without it the default is RS256 via GRANTLAYER_JWT_PRIVATE_KEY/GRANTLAYER_JWT_PUBLIC_KEY (base64-encoded PEM)
GRANTLAYER_ENABLE_OPERATOR_MODEL true Enable the grant request / approval workflow
GRANTLAYER_ENABLE_DEMO_ENDPOINTS false Enable demo tamper endpoints (never in production)
GRANTLAYER_DATABASE_URL (empty = SQLite) PostgreSQL URL when using the postgres profile
GRANTLAYER_HOST 0.0.0.0 Bind address
GRANTLAYER_PORT 8765 HTTP port (inside container)

Copy .env.example to .env — the local-evaluation defaults boot as-is. Calling the API requires JWT material: follow QUICKSTART.md step 1 (RS256 keys) or set legacy GRANTLAYER_JWT_ALGORITHM=HS256 plus GRANTLAYER_JWT_SECRET. Every variable set in .env is forwarded into the containers.


Running locally without Docker

python3 -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
export GRANTLAYER_RUNTIME_MODE=local
export GRANTLAYER_JWT_SECRET=$(python3 -c "import secrets; print(secrets.token_hex(32))")
python3 -m backend

This starts the same FastAPI/uvicorn server as docker compose up. Backend starts at http://127.0.0.1:8765.

GRANTLAYER_RUNTIME_MODE=local selects local-evaluation mode (SQLite auto-provisioning, relaxed gates). Valid values are local, demo, test, staging, production; when the variable is unset the server defaults to production, which deliberately refuses to start without Redis, a strong admin token, and the other hardening settings listed in DEPLOYMENT.md.

Equivalent direct invocation:

uvicorn backend.src.api.app:app --port 8765

Tests

python3 -m pytest backend/tests/ -q -m "not doc_guard"

Or via script: ./scripts/test.sh


Contributing

See CONTRIBUTING.md for coding guidelines, test expectations, and the DCO recommendation. Security reports go to SECURITY.md.

No mature public contribution process is claimed yet — this is a developer preview.


License

Apache License 2.0 — see LICENSE.

About

API-first grant management with verifiable audit trails

Topics

Resources

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages