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.

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]"

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.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

accessgate-0.2.0a1.tar.gz (96.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

accessgate-0.2.0a1-py3-none-any.whl (37.5 kB view details)

Uploaded Python 3

File details

Details for the file accessgate-0.2.0a1.tar.gz.

File metadata

  • Download URL: accessgate-0.2.0a1.tar.gz
  • Upload date:
  • Size: 96.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for accessgate-0.2.0a1.tar.gz
Algorithm Hash digest
SHA256 84badd53c280c772e2141b271ae3a8d604e5f7292e65bcf3d9e1d18bd27d5579
MD5 b273f0723aad1e4a2c7b362732b16a89
BLAKE2b-256 aa58dd6c76fa189122750da220d8b64e6306882e6b455c8cc490aa75b99bcb39

See more details on using hashes here.

Provenance

The following attestation bundles were made for accessgate-0.2.0a1.tar.gz:

Publisher: publish.yaml on Tunet-xyz/access_gate

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file accessgate-0.2.0a1-py3-none-any.whl.

File metadata

  • Download URL: accessgate-0.2.0a1-py3-none-any.whl
  • Upload date:
  • Size: 37.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for accessgate-0.2.0a1-py3-none-any.whl
Algorithm Hash digest
SHA256 3d232a72a9f63f4fcefc87b0bdb46597cb54b8452f7cd128c0bf9fa26aa9a7bb
MD5 b9ddcfcddf4c2c79122b8659ce26c201
BLAKE2b-256 8fce690571186ca5d8e450e041bea41116f1e6f6034435103cd39beff135a9c8

See more details on using hashes here.

Provenance

The following attestation bundles were made for accessgate-0.2.0a1-py3-none-any.whl:

Publisher: publish.yaml on Tunet-xyz/access_gate

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

0.2.0a1 This release

2 files

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