flex_auth.py: CheckRequest + FlexAuthCheckClient against flex-auth's real POST /v1/check contract (schemas/check_request.schema.json, decision_envelope.schema.json, read directly from the flex-auth repo, not guessed). Fail-closed by construction: only effect=="allow" authorizes; every other effect, non-200, malformed body, or transport failure resolves to deny, nothing raises past is_allowed(). authz.FlexAuthWriteAuthorizer implements the existing WriteAuthorizer Protocol. Action -> resource-type mapping coordinated with FLEX-WP-0008's planned vocabulary (both repos reference the same table). DefaultDenyWriteAuthorizer stays the fallback when no flex-auth URL is configured. config.py: Settings.from_env(), mirroring qonto-assistant's pattern. docs/flex-auth-integration.md documents the contract, fail-closed rule, and current real state (denies everything until FLEX-WP-0008 lands). 60 tests passing. Verified live twice over real HTTP between separate processes (not just MockTransport): a deny-returning flex-auth double produces 403 from POST /tenants, an allow-returning one produces 201. Also registered (not implemented) the two workplans this depends on for a complete picture: flex-auth/FLEX-WP-0008 (protected-system registration -- what makes allow reachable) and key-cape/KEY-WP-0005 (discovered key-cape emits none of iam-profile_v0.3.md's core claims yet, not just missing tenant_roles -- a bigger, security-sensitive gap flagged rather than quietly worked around). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
44 lines
959 B
TOML
44 lines
959 B
TOML
[build-system]
|
|
requires = ["setuptools>=68", "wheel"]
|
|
build-backend = "setuptools.build_meta"
|
|
|
|
[project]
|
|
name = "tenant-engine"
|
|
version = "0.1.0"
|
|
description = "Canonical owner of tenant-as-an-entity facts for NetKingdom: existence, onboarding grouping, capability roles, and plan/subscription assignment."
|
|
readme = "README.md"
|
|
requires-python = ">=3.12"
|
|
license = { file = "LICENSE" }
|
|
authors = [{ name = "Coulomb" }]
|
|
dependencies = [
|
|
"fastapi>=0.115,<1.0",
|
|
"uvicorn[standard]>=0.30,<1.0",
|
|
"httpx>=0.27,<1.0",
|
|
]
|
|
|
|
[project.optional-dependencies]
|
|
dev = [
|
|
"pytest>=8.2,<9.0",
|
|
"ruff>=0.6,<1.0",
|
|
]
|
|
|
|
[project.scripts]
|
|
tenant-engine = "tenant_engine.main:main"
|
|
|
|
[tool.setuptools.packages.find]
|
|
where = ["src"]
|
|
|
|
[tool.pytest.ini_options]
|
|
testpaths = ["tests"]
|
|
addopts = [
|
|
"--strict-markers",
|
|
"--disable-warnings",
|
|
"--tb=short",
|
|
]
|
|
|
|
[tool.ruff]
|
|
line-length = 100
|
|
target-version = "py312"
|
|
|
|
[tool.ruff.lint]
|
|
select = ["E", "F", "I", "B"]
|