Skip to content

feat: add gateway action composition boundary#39

Merged
basauth merged 1 commit into
mainfrom
feature/gateway-action-composition
Jun 22, 2026
Merged

feat: add gateway action composition boundary#39
basauth merged 1 commit into
mainfrom
feature/gateway-action-composition

Conversation

@basauth

@basauth basauth commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

Summary

This PR adds an action-composition boundary to basis-gateway.

The change resolves a mismatch identified during action vocabulary reconciliation across the BASIS ecosystem.

Previously:

basis-adapters:
  action = read
  resource_type = ahu

basis-core:
  action = read:ahu

The gateway now supports both kernel-compatible requests and adapter-normalized requests. When a bare action and resource type are provided, the gateway composes a kernel-compatible action string before invoking basis-core.

This preserves the intended architecture:

Adapters normalize protocol operations
        ↓
Gateway assembles runtime requests
        ↓
Core evaluates authorization decisions

The gateway remains the request assembly boundary and does not define authorization policy, protocol semantics, or action vocabulary ownership.


Checklist

Step 1 — Identify affected surfaces

Check every surface this PR touches:

  • Authentication or token verification logic (src/basis_gateway/auth/)
  • Identity normalization or subject mapping (src/basis_gateway/auth/subject_mapper.py)
  • Audit event emission or gateway event vocabulary (src/basis_gateway/audit/)
  • Readiness component registration or behavior (src/basis_gateway/readiness.py)
  • API request/response schemas (src/basis_gateway/api/schemas.py)
  • Environment variable configuration (src/basis_gateway/config.py)
  • Correlation ID handling (src/basis_gateway/middleware/)
  • Public documentation (README.md, docs/)
  • None of the above — this PR does not touch any of these surfaces

Step 2 — Classify the change

  • Additive only (new behavior, new config option, new audit event — existing callers unaffected)
  • Breaking (changes API contract, removes config support, alters audit event shape, changes authentication behavior)
  • Not applicable (docs, tests, refactor only)

If the change affects authentication or audit behavior

  • New or changed behavior is covered by tests
  • Audit event emission for affected paths verified (all pre-evaluation failure paths must emit a gateway event)
  • Security model assumptions in SECURITY.md and docs/release-readiness.md still hold

If the change modifies basis-core integration

  • Change uses only the stable public API (basis-core/docs/public-api.md)
  • No direct imports from basis_core internals

Tests

This PR adds:

  • Action composition helper unit tests
  • Validation tests for bare/composite action handling
  • Validation tests for ambiguous requests
  • Reserved gateway evidence key protection tests
  • Integration tests verifying composed actions reach the evaluator
  • Regression coverage for existing evaluation paths

Validation completed successfully:

  • pytest passes locally (326 passed)
  • ruff check passes
  • ruff format --check passes
  • mypy src passes

@basauth basauth merged commit adb6f9b into main Jun 22, 2026
3 checks passed
@basauth basauth deleted the feature/gateway-action-composition branch June 22, 2026 21:38
@basauth

basauth commented Jun 22, 2026

Copy link
Copy Markdown
Contributor Author

I had Claude verify whether the new action composition evidence is actually emitted through the gateway audit path.

Below is an update to the PR description based on the investigation:

If the change affects authentication or audit behavior

  • New or changed behavior is covered by tests
  • Audit event emission for affected paths verified (decision audit events record the composed action)
  • Security model assumptions in SECURITY.md and docs/release-readiness.md still hold

Audit note:

Composition evidence is injected into DecisionRequest.context before evaluation, but basis-core does not currently copy request context into AuditEvent. Therefore the gateway-owned evidence keys:

basis_gateway.action_composed
basis_gateway.original_action
basis_gateway.resource_type
basis_gateway.composed_action

are not emitted as audit payload fields.

The emitted decision audit event does record the composed action, for example:

read:ahu

rather than the original bare action:

read

This behavior is now covered by a test. Preserving the full composition evidence in emitted audit records would require a separate basis-core audit model change and is intentionally out of scope for this PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants