graph TD
    subgraph ServiceAccounts["Service Accounts"]
        SA_KF["notebook-controller-service-account<br/>(kf-notebook-controller)"]
        SA_ODH["odh-notebook-controller-manager<br/>(odh-notebook-controller)"]
        SA_NB["{notebook-name}<br/>(per-notebook SA)"]
    end

    subgraph ClusterRoleBindings["Cluster Role Bindings"]
        CRB_KF["notebook-controller-role-binding<br/>(cluster-scoped)"]
        CRB_Proxy["notebook-controller-proxy-role-binding<br/>(cluster-scoped)"]
        CRB_ODH["odh-notebook-controller-manager-rolebinding<br/>(cluster-scoped)"]
        RB_Elyra["elyra-pipelines-{notebook-name}<br/>(namespace-scoped, per-notebook)"]
    end

    subgraph ClusterRoles["Cluster Roles"]
        CR_KF["notebook-controller-role"]
        CR_Proxy["notebook-controller-proxy-role"]
        CR_ODH["odh-notebook-controller-manager-role"]
        CR_DSP["ds-pipeline-user-access-dspa"]
    end

    subgraph AggregatedRoles["Aggregated User Roles"]
        CR_Admin["kubeflow-notebooks-admin<br/>(aggregation rule)"]
        CR_Edit["kubeflow-notebooks-edit"]
        CR_View["kubeflow-notebooks-view"]
    end

    %% SA → CRB → CR bindings
    SA_KF -->|"bound via"| CRB_KF
    SA_KF -->|"bound via"| CRB_Proxy
    SA_ODH -->|"bound via"| CRB_ODH
    SA_NB -->|"bound via"| RB_Elyra

    CRB_KF -->|"grants"| CR_KF
    CRB_Proxy -->|"grants"| CR_Proxy
    CRB_ODH -->|"grants"| CR_ODH
    RB_Elyra -->|"grants"| CR_DSP

    %% Aggregation
    CR_Admin -->|"aggregates"| CR_Edit
    CR_Edit -->|"extends"| CR_View

    subgraph KF_Resources["notebook-controller-role Resources"]
        KF_R1["core/pods<br/>get, list, watch, delete"]
        KF_R2["core/events<br/>get, list, watch, create, patch"]
        KF_R3["core/services<br/>*"]
        KF_R4["apps/statefulsets<br/>*"]
        KF_R5["kubeflow.org/notebooks<br/>notebooks/status, notebooks/finalizers<br/>*"]
        KF_R6["networking.istio.io/virtualservices<br/>*"]
    end

    subgraph Proxy_Resources["notebook-controller-proxy-role Resources"]
        Proxy_R1["authentication.k8s.io/tokenreviews<br/>create"]
        Proxy_R2["authorization.k8s.io/subjectaccessreviews<br/>create"]
    end

    subgraph ODH_Resources["odh-notebook-controller-manager-role Resources"]
        ODH_R1["core/configmaps, secrets,<br/>serviceaccounts, services<br/>create, get, list, patch, update, watch"]
        ODH_R2["kubeflow.org/notebooks<br/>get, list, watch, patch, update"]
        ODH_R3["route.openshift.io/routes<br/>create, get, list, watch, update, patch"]
        ODH_R4["oauth.openshift.io/oauthclients<br/>create, delete, get, list, watch, update, patch"]
        ODH_R5["networking.k8s.io/networkpolicies<br/>create, get, list, watch, update, patch"]
        ODH_R6["config.openshift.io/proxies<br/>get, list, watch"]
        ODH_R7["image.openshift.io/imagestreams<br/>get, list, watch"]
        ODH_R8["rbac.authorization.k8s.io/roles, rolebindings<br/>create, get, list, watch, update, patch, delete"]
        ODH_R9["components.platform.opendatahub.io/dashboards<br/>get, list, watch"]
        ODH_R10["datasciencepipelinesapplications.opendatahub.io<br/>get, list, watch"]
    end

    subgraph User_Resources["User Role Resources"]
        User_R1["kubeflow.org/notebooks, notebooks/status<br/>get, list, watch, create, delete,<br/>deletecollection, patch, update"]
    end

    CR_KF -->|"grants access to"| KF_Resources
    CR_Proxy -->|"grants access to"| Proxy_Resources
    CR_ODH -->|"grants access to"| ODH_Resources
    CR_Edit -->|"grants access to"| User_Resources

    %% Styling
    style SA_KF fill:#4a90e2,stroke:#333,color:#fff
    style SA_ODH fill:#4a90e2,stroke:#333,color:#fff
    style SA_NB fill:#4a90e2,stroke:#333,color:#fff
    style CR_KF fill:#f5a623,stroke:#333,color:#000
    style CR_Proxy fill:#f5a623,stroke:#333,color:#000
    style CR_ODH fill:#f5a623,stroke:#333,color:#000
    style CR_DSP fill:#f5a623,stroke:#333,color:#000
    style CR_Admin fill:#bd10e0,stroke:#333,color:#fff
    style CR_Edit fill:#bd10e0,stroke:#333,color:#fff
    style CR_View fill:#bd10e0,stroke:#333,color:#fff
