feat: add fail-closed Hub access profile foundation
Assistant: codex Assistant-Model: gpt-6-astra Assistant-Session: 01a0e747-8f27-7242-8df8-8bc44f88c929
This commit is contained in:
parent
df39fd5f43
commit
3e386147fd
35 changed files with 2009 additions and 195 deletions
|
|
@ -25,6 +25,21 @@ def get_contract_validator(request: Request) -> ContractValidator:
|
|||
return request.app.state.contract_validator
|
||||
|
||||
|
||||
def _attribute_event(body: EventCommand, request: Request) -> EventCommand:
|
||||
context = getattr(request.state, "hub_access", None)
|
||||
if context is None:
|
||||
return body
|
||||
# Reserved server provenance overrides any payload assertion. Domain
|
||||
# subject_refs remain business data and are never authentication evidence.
|
||||
return body.model_copy(update={"payload": {**body.payload, "_hub_access": {
|
||||
"issuer": context.actor.issuer, "subject": context.actor.subject,
|
||||
"principal_type": context.actor.principal_type,
|
||||
"actor_tenant": context.actor.tenant,
|
||||
"target_tenant": context.facts.target_tenant,
|
||||
"correlation_id": context.correlation_id,
|
||||
}}})
|
||||
|
||||
|
||||
def create_ports_router() -> APIRouter:
|
||||
router = APIRouter(prefix="/ports")
|
||||
|
||||
|
|
@ -112,6 +127,7 @@ def create_ports_router() -> APIRouter:
|
|||
)
|
||||
async def append_progress(
|
||||
body: EventCommand,
|
||||
request: Request,
|
||||
store: PortStore = Depends(get_port_store),
|
||||
validator: ContractValidator = Depends(get_contract_validator),
|
||||
) -> PortAccepted:
|
||||
|
|
@ -119,7 +135,7 @@ def create_ports_router() -> APIRouter:
|
|||
validator.validate_event_family(body.event_type, "progress")
|
||||
except ValueError as exc:
|
||||
raise HTTPException(status_code=422, detail=str(exc)) from exc
|
||||
return await store.append_progress(body)
|
||||
return await store.append_progress(_attribute_event(body, request))
|
||||
|
||||
@router.post(
|
||||
"/events/interaction",
|
||||
|
|
@ -130,6 +146,7 @@ def create_ports_router() -> APIRouter:
|
|||
)
|
||||
async def append_interaction(
|
||||
body: EventCommand,
|
||||
request: Request,
|
||||
store: PortStore = Depends(get_port_store),
|
||||
validator: ContractValidator = Depends(get_contract_validator),
|
||||
) -> PortAccepted:
|
||||
|
|
@ -137,7 +154,7 @@ def create_ports_router() -> APIRouter:
|
|||
validator.validate_event_family(body.event_type, "interaction")
|
||||
except ValueError as exc:
|
||||
raise HTTPException(status_code=422, detail=str(exc)) from exc
|
||||
return await store.append_interaction(body)
|
||||
return await store.append_interaction(_attribute_event(body, request))
|
||||
|
||||
@router.get(
|
||||
"/projections/{projection_id}",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue