Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

AccessGate

Composable, default-deny RBAC, ABAC, and relationship-aware authorization for Python applications.

AccessGate answers one question: may this subject perform this action on this resource in this context? It provides a small framework-neutral kernel, secure decision defaults, and extension interfaces for application-specific identity, policy, audit, and framework integration.

It is complementary to authentication and session-security packages such as SessionArmor. Those establish who the caller is and whether the session can be trusted; AccessGate decides what that caller is allowed to do.

For Django, the integration is explicit and deny-only:

from access_gate import AuthorizationEngine, RolePolicy, SessionAssurancePolicy

engine = AuthorizationEngine([
    SessionAssurancePolicy(actions={"records.read"}),
    RolePolicy({"records_reader"}, actions={"records.read"}),
])

The default Django adapter carries SessionArmor's versioned request.session_assurance evidence into authorization context without a hard package dependency. Missing, stale, malformed, future-dated, unbound, or subject-mismatched evidence denies; valid evidence never grants by itself.

Status: early alpha. Security controls and assurance evidence are being developed rigorously, but the public API may evolve before 1.0. This package has not received an independent audit or any government/NATO accreditation.

Design guarantees

  • Default deny: abstention never grants access.
  • Deny overrides: any explicit denial wins over grants by default.
  • Fail closed: policy and audit failures deny access by default.
  • Exact matching: built-in role, action, owner, and tenant comparisons never use substring matching.
  • Safe ABAC: missing attributes and operator failures are indeterminate, cannot be negated into access, and deny by default.
  • Immutable inputs: request attributes, literal values, and decision metadata are recursively snapshotted before evaluation or audit.
  • Bounded evaluation: serialized policies, condition trees, MCP messages, and collection workloads have explicit denial-of-service limits.
  • Verifiable policy identity: canonical fingerprints, ordered policy-set fingerprints, externally verified signed envelopes, and engine-owned policy deployment identifiers support change control without embedding key custody.
  • No expression evaluation: declarative policies use registered operators and mapping-only attribute traversal—never Python eval or object traversal.
  • Framework-neutral core: no runtime dependencies and no ORM, token, or user model assumptions.
  • Custom from day one: policies, decision strategies, identity/resource resolvers, audit sinks, and framework adapters are public extension points.

Subject, Resource, AuthorizationRequest, and Decision expose to_dict() for JSON-friendly snapshots of their otherwise immutable data.

Installation

pip install AccessGate

For the optional Django adapter:

pip install "AccessGate[django]"

The package root remains framework-neutral. Django integration is imported explicitly from the adapter namespace:

from access_gate.adapters.django import DjangoAuthorizer

Quick start

from access_gate import (
    AuthorizationEngine,
    Resource,
    RolePolicy,
    Subject,
    TenantBoundaryPolicy,
)

engine = AuthorizationEngine(
    [
        TenantBoundaryPolicy(actions={"incident.read"}),
        RolePolicy({"incident_manager"}, actions={"incident.read"}),
    ]
)

decision = engine.authorize(
    Subject(
        "user-42",
        roles=frozenset({"incident_manager"}),
        attributes={"tenant_id": "acme"},
    ),
    "incident.read",
    Resource("incident", "INC-123", {"tenant_id": "acme"}),
)

assert decision.allowed

Tenant boundaries deliberately do not grant access. They abstain when the tenant matches and deny when it is missing or different; another policy must positively allow the action.

Attribute-based access control

ABAC policies can compare subject, resource, action, and context attributes:

from access_gate import (
    ActionAttribute,
    AllOf,
    AttributePolicy,
    ContextAttribute,
    ResourceAttribute,
    SubjectAttribute,
)

document_access = AttributePolicy(
    AllOf(
        SubjectAttribute("department").equals(ResourceAttribute("department")),
        SubjectAttribute("clearance").greater_than_or_equal(
            ResourceAttribute("classification")
        ),
        ActionAttribute("risk").less_than_or_equal(3),
        ContextAttribute("device.trusted").equals(True),
    ),
    actions={"document.read"},
    name="document_access",
)

Conditions support AllOf, AnyOf, and Not, multi-valued attributes, exact membership and set relations, numeric comparisons, and explicit existence checks. Not preserves indeterminate outcomes, so a missing attribute never becomes a grant merely because a condition was negated.

Policies serialize to the versioned access_gate.policy.v1 format:

from access_gate import dumps_policy, loads_policy

document = dumps_policy(document_access)
restored = loads_policy(document)

For controlled deployments, identify the exact ordered policy set and pass that identifier into the engine so every final and audited decision is attributable:

from access_gate import AuthorizationEngine, policy_set_fingerprint

policy_set_id = policy_set_fingerprint([document_access])
engine = AuthorizationEngine([document_access], policy_set_id=policy_set_id)

dumps_signed_policy() and loads_signed_policy() accept application-supplied signer/verifier protocols. AccessGate deliberately does not choose algorithms, store keys, or implement a trust store. See docs/POLICY_FORMAT.md.

See docs/abac.md for the full data model, operator semantics, customization rules, JSON format, and rollout guidance.

Application-defined policies

Implement the Policy protocol directly or wrap a function:

from access_gate import Decision, FunctionPolicy

def published_incidents(request):
    resource = request.resource
    if resource and resource.attributes.get("published") is True:
        return Decision.allow("The incident is public.", policy="published")
    return None

policy = FunctionPolicy("published", published_incidents)

A policy returns an allow/deny Decision, or None to abstain. Custom decision strategies can replace deny-overrides where a domain needs different semantics. Policies exposing a validated frozenset in an actions attribute are indexed by the engine and skipped for unrelated actions. FunctionPolicy supports this directly through its actions argument. Use decide_many() for ordered batch evaluation; every request still receives its own decision and audit event.

For mixed RBAC/ABAC grants, configure alternative grant policies to abstain on a miss. Explicit boundary denials still override every grant.

Django adapter

from access_gate import AuthorizationEngine, RolePolicy
from access_gate.adapters.django import DjangoAuthorizer

authorizer = DjangoAuthorizer(
    AuthorizationEngine([RolePolicy({"admin"}, actions={"users.list"})])
)

@authorizer.require("users.list")
def user_list(request):
    ...

The default Django subject resolver only reads pk, is_authenticated, access_gate_roles, and access_gate_attributes. Real applications should normally provide a resolver that validates and maps their exact identity claims. The adapter also accepts custom context and action-attribute resolvers for ABAC. Synchronous and asynchronous Django views are supported. Async views may use awaitable subject, resource, context, action-attribute, and denial resolvers.

MCP server

AccessGate includes a dependency-free stdio MCP server:

accessgate-mcp

From a source checkout, run python mcp/server.py. The server exposes package capabilities, authorization-model guidance, the ABAC JSON Schema, exact built-in operator discovery, and read-only policy validation. It does not authenticate users, evaluate production identity data, or change application policy.

Project boundary

AccessGate does not authenticate users, validate JWTs, secure sessions, query application permissions, or decide how tenants and resources are represented. Those are application and adapter responsibilities. See docs/architecture.md and docs/customization.md. AccessGate provides its own policy format but does not claim wire compatibility with XACML, Cedar, Rego, or other policy languages.

Development

python -m pip install -e ".[dev]"
ruff check src tests
mypy src/access_gate
pytest --cov=access_gate --cov-report=term-missing

Security reviewers should begin with the threat model, assurance case, and audit scope.

License

MIT (c) Tunet Ltd.

Metadata

Release files for AccessGate 0.3.0a1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for AccessGate 0.3.0a1
File Size Uploaded Provenance Actions
accessgate-0.3.0a1.tar.gz 99.3 kB With provenance Details for accessgate-0.3.0a1.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for AccessGate 0.3.0a1
File Interpreter ABI Platform Actions
accessgate-0.3.0a1-py3-none-any.whl Python 3 none any Details for accessgate-0.3.0a1-py3-none-any.whl

Total release size: 138.4 kB

Release files / accessgate-0.3.0a1.tar.gz

Download URL accessgate-0.3.0a1.tar.gz
Size 99.3 kB
Tags Source
SHA-256 checksum
How to use checksums
35b34e509a6e324f2707b6251294644458e36617119764f710be1364071a0dce
BLAKE2b-256 checksum
How to use checksums
6c25f4d03064784c8ba513e27fe39818594d7af5cc473f059c2435cc4a8ca158
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 17, 2026.

Transparency log

Release files / accessgate-0.3.0a1-py3-none-any.whl

Download URL accessgate-0.3.0a1-py3-none-any.whl
Size 39.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e2bb82c03ecade0cf3f1b27c80ac6176c23346c981403b4279c33103faa0f102
BLAKE2b-256 checksum
How to use checksums
2b96ccbcd947ea527b5232f00235c4111ec32883ffa6b2c4401391cded7d1f72
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 17, 2026.

Transparency log

Security for AccessGate 0.3.0a1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for accessgate-0.3.0a1.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 17, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page