# PP-1411 Architecture Diagrams

---

## Option 1: Policy-driven fetch from ows-permissions

### Architecture overview

```mermaid
flowchart LR
    Client([Client])

    subgraph pdp["ows-pdp"]
        PMD[(PolicyMetadataDB\nin-memory)]
        BP["_build_principal\n(merge roles)"]
    end

    OWS["ows-permissions"]
    Neo4j[("Neo4j\nLabelProfile nodes")]
    Cerbos["Cerbos"]

    Client -->|"POST /self/check/resources/"| pdp
    pdp -->|"if workstation_roles needed"| OWS
    OWS -->|"MATCH LabelProfile"| Neo4j
    Neo4j -->|"roles per vendor"| OWS
    OWS -->|"workstation roles"| pdp
    pdp -->|"CheckResources\n(principal + resources)"| Cerbos
    Cerbos -->|"allow / deny"| pdp
    pdp -->|response| Client
```

### Request flow

```mermaid
sequenceDiagram
    participant C as Client
    participant PDP as ows-pdp
    participant PMD as PolicyMetadataDB
    participant OWS as ows-permissions
    participant N4J as Neo4j
    participant CRB as Cerbos

    C->>PDP: POST /identity/self/check/resources/

    PDP->>PMD: requires_workstation_roles(resource_type)?
    PMD-->>PDP: true

    PDP->>OWS: GET /identity/{uuid}/workstation-roles/
    OWS->>N4J: MATCH LabelProfile nodes for identity
    N4J-->>OWS: [{vendor_uuid, roles: ["administrator"]}]
    OWS-->>PDP: workstation roles by vendor

    Note over PDP: _build_principal merges workstation_roles<br/>alongside pdp_tenant_roles and ows_permissions_tenant_roles

    PDP->>CRB: CheckResources(principal, resources)
    CRB-->>PDP: [{resource, actions: {allow/deny}}]
    PDP-->>C: CheckResourcesResponse
```

---

## Option 2: Kafka CDC dual-write → DynamoDB

### Architecture overview

```mermaid
flowchart TD
    subgraph writes["Write paths into Neo4j"]
        GQL["graphql-user"]
        DBP["database PRs"]
        N4JR["neo4j refresh"]
    end

    N4J[("Neo4j\nLabelProfile nodes")]
    CDC["Neo4j CDC\nSource Connector"]
    KFK["Kafka topic\ncdc.musicGraphV5.*"]
    LMB["Lambda consumer"]
    DDB[("DynamoDB\npp_identity")]

    subgraph pdp["ows-pdp (read path)"]
        BP["_build_principal\n(reads from pdp_tenant_roles)"]
    end

    CRB["Cerbos"]
    Client([Client])

    GQL --> N4J
    DBP --> N4J
    N4JR --> N4J

    N4J -->|"change events"| CDC
    CDC -->|"messages"| KFK
    KFK -->|"consume"| LMB
    LMB -->|"resolve identity + vendor\nby profile_uuid"| N4J
    N4J -->|"identity_uuid, vendor_uuid"| LMB
    LMB -->|"update_tenant_permissions\n(add workstation_roles)"| DDB

    Client -->|"POST /self/check/resources/"| pdp
    DDB -->|"pdp_tenant_roles\n(includes workstation_roles)"| pdp
    pdp -->|"CheckResources"| CRB
    CRB -->|"allow / deny"| pdp
    pdp -->|response| Client
```

### Async write path

```mermaid
sequenceDiagram
    participant SRC as graphql-user / DB PR
    participant N4J as Neo4j
    participant CDC as CDC Connector
    participant KFK as Kafka
    participant LMB as Lambda
    participant DDB as DynamoDB (pp_identity)

    SRC->>N4J: write LabelProfile roles
    N4J->>CDC: change event (profile_uuid, roles updated)
    CDC->>KFK: publish message

    KFK->>LMB: consume event (profile_uuid, roles)
    LMB->>N4J: MATCH (i:Identity)-[:HAS_PROFILE]-(p {uuid})-[:HAS_ACCESS_TO]-(v:Vendor)
    N4J-->>LMB: identity_uuid, vendor_uuid

    LMB->>DDB: update_tenant_permissions(identity_uuid, vendor_uuid, workstation_roles)

    Note over KFK,DDB: Asynchronous — brief lag between Neo4j write and DDB update
```

### Read path (authorization check)

```mermaid
sequenceDiagram
    participant C as Client
    participant PDP as ows-pdp
    participant PMD as PolicyMetadataDB
    participant DDB as DynamoDB (pp_identity)
    participant CRB as Cerbos

    C->>PDP: POST /identity/self/check/resources/

    PDP->>DDB: load pdp_tenant_roles for identity
    DDB-->>PDP: roles (contract_viewer, workstation_administrator, ...)

    PDP->>PMD: requires_workstation_roles(resource_type)?
    PMD-->>PDP: true

    Note over PDP: workstation_roles already in pdp_tenant_roles<br/>_build_principal reads them — no extra HTTP call

    PDP->>CRB: CheckResources(principal with workstation_roles, resources)
    CRB-->>PDP: [{resource, actions: {allow/deny}}]
    PDP-->>C: CheckResourcesResponse
```

---

## Side-by-side comparison

```mermaid
flowchart LR
    subgraph opt1["Option 1 — synchronous fetch"]
        direction TB
        C1([Client]) --> P1["ows-pdp"]
        P1 -->|"if needed"| OWS["ows-permissions"]
        OWS --> Neo["Neo4j"]
        Neo --> OWS
        OWS --> P1
        P1 --> CRB1["Cerbos"]
    end

    subgraph opt2["Option 2 — roles pre-loaded in DynamoDB"]
        direction TB
        C2([Client]) --> P2["ows-pdp"]
        DDB[("DynamoDB\n(roles pre-written\nvia Lambda)")] --> P2
        P2 --> CRB2["Cerbos"]
    end
```
