identity.mmd
Part of the StackToIT package, published unchanged. A file of a proposal: nothing here is approved or applied.
%% FOR REVIEW — generated by StackToIT Assess. Architect review required before any decision.
%% Run `6f8f72b2-1c34-4cfc-8483-344c41245364` · source digest `sha256:19bfed642d5789ccada81b91d5c36e33175dcafd66dc46b1644ffa105d020000`
%% What this view is: the identity transition of each GCP service account: the service account and the workloads that run as it, the roles the source grants it, the migration decision (the class and confidence the assessment gives it and the decisions the plans list for it), the STACKIT identity the plans draft, the role assignment and the scope of the target resource.
%% The plans hold no role assignment of their own: the step is drawn as drafted where a block of the draft assigns a role to the STACKIT identity, with the role (the draft supplies it by a variable the architect fills: a Google Cloud role is not translated into a STACKIT role), the scope, the grants of the source it replaces and what it grants beyond them, all taken from the record the converter makes of that block; it is drawn as manual (a person chooses the roles) where neither a plan nor the draft holds one, and the roles and the scope are UNKNOWN (dashed) where the record of a drafted block states none. The manual actions the identity plan states are drawn either way. A service account no plan holds a STACKIT identity for is a dashed edge with the plan's reason; the draft may still write one that the plans do not type, and the box names the service the assessment proposes.
%% The column "Roles the source grants" is what the source states and nothing else: a role binding or member of the service account on a project or a resource, an authoritative policy (whose roles are not read), and the grants made on the account (who may act as it; the Kubernetes service accounts bound to it by Workload Identity). A role the source writes as a variable, or a member it writes as a text the scan cannot resolve, is said so.
%% A thin arrow is a reference or a hand-over; a thick arrow is a path the plan permits; a dashed arrow is UNKNOWN; an orange arrow is MANUAL. assurance/identity-transition.md holds the credential and federation facts of each principal.
%% A box whose text ends in "full text at the end of this file" is cut at the end of a clause: the lines "Full text of box" at the end of this file carry the whole text, and the drawn view prints it.
flowchart LR
subgraph g_principal["GCP service account"]
n_google_cloud_run_v2_job_migrate["google_cloud_run_v2_job.migrate<br/><small>google_cloud_run_v2_job</small>"]:::unit
n_google_cloud_run_v2_service_server["google_cloud_run_v2_service.server<br/><small>google_cloud_run_v2_service</small>"]:::unit
n_google_service_account_automation["google_service_account.automation<br/><small>google_service_account</small>"]:::unit
n_google_service_account_client["google_service_account.client<br/><small>google_service_account</small>"]:::unit
n_google_service_account_init["google_service_account.init<br/><small>google_service_account</small>"]:::unit
n_google_service_account_server["google_service_account.server<br/><small>google_service_account</small>"]:::unit
end
subgraph g_grants["Roles the source grants"]
n_grant_google_project_iam_member_automation_permissions_google_service_account_automation["role not settled (unknown iteration)<br/>@ project example-project<br/>google_project_iam_member.automation_permissions"]:::synthetic
n_grant_google_project_iam_member_client_permissions_google_service_account_client["role not settled (unknown iteration)<br/>@ project example-project<br/>google_project_iam_member.client_permissions"]:::synthetic
n_grant_google_project_iam_member_init_permissions_google_service_account_init["role not settled (unknown iteration)<br/>@ project example-project<br/>google_project_iam_member.init_permissions"]:::synthetic
n_grant_google_project_iam_member_server_permissions_google_service_account_server["role not settled (unknown iteration)<br/>@ project example-project<br/>google_project_iam_member.server_permissions"]:::synthetic
n_grant_google_secret_manager_secret_iam_binding_django_admin_password_google_service_account_automation["role roles/secretmanager.secretAccessor<br/>@ google_secret_manager_secret.django_admin_password<br/>google_secret_manager_secret_iam_binding.django_admin_password"]:::synthetic
n_grant_google_secret_manager_secret_iam_binding_django_settings_google_service_account_automation["role roles/secretmanager.secretAccessor<br/>@ google_secret_manager_secret.django_settings<br/>google_secret_manager_secret_iam_binding.django_settings"]:::synthetic
n_grant_google_secret_manager_secret_iam_binding_django_settings_google_service_account_server["role roles/secretmanager.secretAccessor<br/>@ google_secret_manager_secret.django_settings<br/>google_secret_manager_secret_iam_binding.django_settings"]:::synthetic
n_grant_google_storage_bucket_iam_member_automation_google_service_account_automation["role roles/storage.admin<br/>@ google_storage_bucket.media<br/>google_storage_bucket_iam_member.automation"]:::synthetic
n_grant_google_storage_bucket_iam_member_server_google_service_account_server["role roles/storage.admin<br/>@ google_storage_bucket.media<br/>google_storage_bucket_iam_member.server"]:::synthetic
end
subgraph g_decision["Migration decision"]
n_decision_google_service_account_automation["decision: RECONFIGURE · MEDIUM"]:::synthetic
n_decision_google_service_account_client["decision: RECONFIGURE · MEDIUM"]:::synthetic
n_decision_google_service_account_init["decision: RECONFIGURE · MEDIUM"]:::synthetic
n_decision_google_service_account_server["decision: RECONFIGURE · MEDIUM"]:::synthetic
end
subgraph g_identity["STACKIT identity"]
n_stackit_service_account_automation["stackit_service_account.automation<br/><small>stackit_service_account</small>"]:::unit
n_stackit_service_account_client["stackit_service_account.client<br/><small>stackit_service_account</small>"]:::unit
n_stackit_service_account_init["stackit_service_account.init<br/><small>stackit_service_account</small>"]:::unit
n_stackit_service_account_server["stackit_service_account.server<br/><small>stackit_service_account</small>"]:::unit
end
subgraph g_assignment["Role assignment"]
n_assignment_google_service_account_automation["role assignment<br/>manual: roles are chosen by a person"]:::manual
n_assignment_google_service_account_client["role assignment<br/>manual: roles are chosen by a person"]:::manual
n_assignment_google_service_account_init["role assignment<br/>manual: roles are chosen by a person"]:::manual
n_assignment_google_service_account_server["role assignment<br/>manual: roles are chosen by a person"]:::manual
n_manual_google_service_account_automation_0["manual action<br/>Decide who may use the STACKIT service account written for google_service_account.automation … (full text at the end of this file)"]:::manual
n_manual_google_service_account_server_0["manual action<br/>Decide who may use the STACKIT service account written for google_service_account.server … (full text at the end of this file)"]:::manual
end
subgraph g_scope["Target resource scope"]
n_scope_unknown["target resource scope<br/>not typed in the plan"]:::unknown
end
n_assignment_google_service_account_automation -.->|"unknown: the scope of the roles goes with the roles"| n_scope_unknown
n_assignment_google_service_account_client -.->|"unknown: the scope of the roles goes with the roles"| n_scope_unknown
n_assignment_google_service_account_init -.->|"unknown: the scope of the roles goes with the roles"| n_scope_unknown
n_assignment_google_service_account_server -.->|"unknown: the scope of the roles goes with the roles"| n_scope_unknown
n_decision_google_service_account_automation ==>|"drafted: a block of the draft, not a plan resource"| n_stackit_service_account_automation
n_decision_google_service_account_client ==>|"drafted: a block of the draft, not a plan resource"| n_stackit_service_account_client
n_decision_google_service_account_init ==>|"drafted: a block of the draft, not a plan resource"| n_stackit_service_account_init
n_decision_google_service_account_server ==>|"drafted: a block of the draft, not a plan resource"| n_stackit_service_account_server
n_google_cloud_run_v2_job_migrate -->|"runs as: template.template.service_account"| n_google_service_account_automation
n_google_cloud_run_v2_service_server -->|"runs as: template.service_account"| n_google_service_account_server
n_google_service_account_automation -->|"migration decision"| n_decision_google_service_account_automation
n_google_service_account_automation -.->|"granted in the source"| n_grant_google_project_iam_member_automation_permissions_google_service_account_automation
n_google_service_account_automation -->|"granted in the source"| n_grant_google_secret_manager_secret_iam_binding_django_admin_password_google_service_account_automation
n_google_service_account_automation -->|"granted in the source"| n_grant_google_secret_manager_secret_iam_binding_django_settings_google_service_account_automation
n_google_service_account_automation -->|"granted in the source"| n_grant_google_storage_bucket_iam_member_automation_google_service_account_automation
n_google_service_account_client -->|"migration decision"| n_decision_google_service_account_client
n_google_service_account_client -.->|"granted in the source"| n_grant_google_project_iam_member_client_permissions_google_service_account_client
n_google_service_account_init -->|"migration decision"| n_decision_google_service_account_init
n_google_service_account_init -.->|"granted in the source"| n_grant_google_project_iam_member_init_permissions_google_service_account_init
n_google_service_account_server -->|"migration decision"| n_decision_google_service_account_server
n_google_service_account_server -.->|"granted in the source"| n_grant_google_project_iam_member_server_permissions_google_service_account_server
n_google_service_account_server -->|"granted in the source"| n_grant_google_secret_manager_secret_iam_binding_django_settings_google_service_account_server
n_google_service_account_server -->|"granted in the source"| n_grant_google_storage_bucket_iam_member_server_google_service_account_server
n_stackit_service_account_automation -->|"manual: neither the plan nor the draft holds a role assignment"| n_assignment_google_service_account_automation
n_stackit_service_account_automation -->|"manual"| n_manual_google_service_account_automation_0
n_stackit_service_account_client -->|"manual: neither the plan nor the draft holds a role assignment"| n_assignment_google_service_account_client
n_stackit_service_account_init -->|"manual: neither the plan nor the draft holds a role assignment"| n_assignment_google_service_account_init
n_stackit_service_account_server -->|"manual: neither the plan nor the draft holds a role assignment"| n_assignment_google_service_account_server
n_stackit_service_account_server -->|"manual"| n_manual_google_service_account_server_0
linkStyle 23,24,25,26,27,28 stroke:#a8650c,stroke-width:2px
classDef unit fill:#e1e5f5,stroke:#4b5ba6
classDef synthetic fill:#f3f3f3,stroke:#566663
classDef unknown fill:#f3f3f3,stroke:#566663,stroke-dasharray:4 3
classDef manual fill:#f6e7cf,stroke:#a8650c
classDef internet fill:#f8deda,stroke:#b1261b
%% Full text of box manual:google_service_account.automation:0: manual action · Decide who may use the STACKIT service account written for google_service_account.automation, what it may do and which workloads run as it: the draft attaches it to nothing
%% Full text of box manual:google_service_account.server:0: manual action · Decide who may use the STACKIT service account written for google_service_account.server, what it may do and which workloads run as it: the draft attaches it to nothing