# Architecture ## Ownership model Catalog는 환경이 아니라 workload ownership으로 나눕니다. | Area | Owned resources | | --- | --- | | `gitops/apps/auth-server` | auth-server | | `gitops/apps/identity-postgres` | identity-postgres | | `gitops/apps/auth-migration` | versioned Flyway Job | | `gitops/platform` | Vault, Keycloak, MinIO, registry와 operator | | `gitops/platform/forward-auth` | oauth2-proxy와 Traefik ForwardAuth integration | 환경별 차이는 각 catalog의 `overlays/`에 두고, rollout ownership은 `gitops/clusters///stages`가 가집니다. 따라서 경로만 보고 리소스 소유자와 실제 적용 단계를 구분할 수 있습니다. ## Deployment graph ```text namespaces | 00-platform ---- cert-manager / Keycloak Operator / Traefik policy | +---- Helm: MinIO Operator / Vault Secrets Operator | 10-vault ---- Vault Running -> init/unseal/policies/roles -> KV seed | 20-secrets ---- VaultConnection / VaultAuth / pre-data VaultStaticSecret | 30-data ---- PostgreSQL / MinIO / Keycloak | +---- MinIO registry bucket/access-key provisioning -> Vault | 35-registry ---- registry VaultStaticSecret / docker-registry | 40-operations ---- auth-server-migrate-0-1-0 / platform-realm-v1 | 50-apps ---- auth-server / oauth2-proxy / ingress ``` `all/`은 이 그래프를 하나로 렌더하지만 실행 순서를 보장하지 않습니다. 따라서 validation 전용입니다. ## Runtime boundaries | Workload | Kind | Namespace | Base | | --- | --- | --- | --- | | Vault | StatefulSet | `mnt` | `gitops/platform/vault` | | identity-postgres | StatefulSet | `mnt` | `gitops/apps/identity-postgres` | | MinIO | Tenant CR | `mnt` | `gitops/platform/minio` | | Keycloak | Keycloak CR | `mnt` | `gitops/platform/keycloak` | | docker-registry | Deployment | `mnt` | `gitops/platform/registry` | | auth-server | Deployment | `mnt` | `gitops/apps/auth-server` | | oauth2-proxy | Deployment | `mnt` | `gitops/platform/forward-auth` | | DB migration | Job | `mnt` | `gitops/apps/auth-migration` | | realm import | KeycloakRealmImport | `mnt` | `gitops/apps/keycloak-realm-import` | ## One-shot operation contract Flyway Job 이름은 migration release를 포함합니다: `auth-server-migrate-0-1-0`. SQL을 변경해 새 migration release를 만들 때는 Job instance/name도 함께 올립니다. 같은 이름의 완료된 Job을 지웠다가 묵시적으로 재실행하지 않습니다. KeycloakRealmImport도 `platform-realm-v1`처럼 versioned name을 씁니다. Operator는 기존 import CR의 spec 변경을 일반 workload rollout처럼 재실행하지 않으므로, realm 변경은 새 version의 명시적 operation으로 냅니다. ## Namespace decision 현재 lab은 `mnt` 단일 namespace입니다. 이는 운영 권장 구조가 아니라 기존 runtime을 깨지 않고 먼저 deployment lifecycle을 분리하기 위한 전환 단계입니다. 역할별 namespace 분리는 다음을 원자적으로 바꿔야 합니다. - Service DNS와 issuer/JWK/DB endpoint - Vault Kubernetes auth의 bound ServiceAccount/namespace - VSO destination Secret 위치 - cross-namespace NetworkPolicy - Flyway와 DB init credential ownership - operator watch namespace와 RBAC 따라서 단순 폴더 이동과 함께 수행하지 않습니다. ## Environment meaning - `lab`: 폐기 가능한 K3s 검증 환경. stateful overlay의 local-path, HTTP ingress, 단일 replica 허용. - `staging`: production과 같은 보안·TLS·backup path의 승격 검증 환경. - `prod`: HA, digest pin, backup/restore evidence, TLS, disruption budget가 준비되지 않으면 생성하지 않습니다.