Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 54 additions & 5 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,26 @@ Compatibility mode is route-based and extensible:
- converts selected `primary` booleans to string values
- adds flattened enterprise manager alias key

Management security is profile-based:

- Default profile is `azure`, using interactive Azure OIDC login.
- `cloudflare` profile switches the management apps to JWT resource-server mode.
- Cloudflare mode reads the token from `Cf-Access-Jwt-Assertion` by default and maps roles from a configurable claim.
- Shared helpers live in `scim-server-common` (`AzureOidcSecuritySupport`, `CloudflareJwtSecuritySupport`, `MgmtSecuritySupport`).

Kubernetes support is split into two trees:

- `k8s/app/**` deploys the namespaced SCIM stack in `scim`:
- CloudNativePG PostgreSQL cluster
- validator database resource
- API, management, and validator-mgmt Deployments and Services
- `k8s/cluster/**` deploys supporting cluster resources:
- local-path storage configuration and `local-path-custom` `StorageClass`
- `cloudflared` in its own namespace

Kubernetes secrets are stored as `*.sops.yaml` files and rendered through `ksops`.
The root `.sops.yaml` defines the active age recipient.

## Build And Run

```bash
Expand All @@ -41,14 +61,25 @@ mvn clean install -pl '!scim-validator'
# API local mode (requires datasource env vars and ACTUATOR_API_KEY)
cd scim-server-api && mvn spring-boot:run

# Mgmt UI/API local mode (requires datasource env vars, ACTUATOR_API_KEY, and Azure OIDC env vars)
# Mgmt UI/API local mode (defaults to Azure profile; requires datasource env vars,
# ACTUATOR_API_KEY, and Azure OIDC env vars unless you explicitly set SPRING_PROFILES_ACTIVE=cloudflare)
cd scim-server-mgmt && mvn spring-boot:run

# Validator management local mode (requires datasource env vars, ACTUATOR_API_KEY, and Azure OIDC env vars)
# Validator management local mode (defaults to Azure profile; requires datasource env vars,
# ACTUATOR_API_KEY, and Azure OIDC env vars unless you explicitly set SPRING_PROFILES_ACTIVE=cloudflare)
cd scim-validator-mgmt && mvn spring-boot:run

# Docker stack (PostgreSQL 18 + API + mgmt + validator mgmt)
# Docker stack
docker compose up --build

# Docker stack plus local cloudflared sidecar
docker compose --profile cloudflare up --build

# Kubernetes support resources (requires kubectl, kustomize, ksops, sops, and SOPS_AGE_KEY_FILE)
kustomize build --enable-alpha-plugins --enable-exec k8s/cluster | kubectl apply -f -

# Kubernetes application stack
kustomize build --enable-alpha-plugins --enable-exec k8s/app | kubectl apply -f -
```

Docker default ports:
Expand All @@ -58,6 +89,12 @@ Docker default ports:
- Validator Mgmt `:8082`
- PostgreSQL `:5432`

Operational notes:

- `docker-compose.yml` loads `docker/env/cloudflare.env` into the management apps.
- Kubernetes manifests set `SPRING_PROFILES_ACTIVE=cloudflare` for the management apps.
- Application services in Kubernetes are `ClusterIP`; Cloudflare tunnel is the external-access path in this branch.

## Validator Execution

`scim-validator` can either bootstrap its own disposable target via
Expand All @@ -84,9 +121,13 @@ Notes from `ScimBaseSpec`:
- SCIM mapping code uses static utility classes (`ScimUserMapper`, `ScimGroupMapper`, `MsScimUserMapper`).
- Java records are used in DTO layers (notably in mgmt and validator-mgmt modules).
- `@Transactional` appears on service classes and on selected controller classes/methods. Preserve existing boundaries unless intentionally refactoring.
- Flyway migrations are split by concern:
- shared schema migrations under `db/common`
- validator schema migrations under `db/validator`
- module-specific migrations under `db/migration`
- Content types:
- SCIM endpoints: `application/scim+json`
- Mgmt endpoints: standard JSON (`application/json`)
- SCIM endpoints: `application/scim+json`
- Mgmt endpoints: standard JSON (`application/json`)

## Data Model Patterns

Expand Down Expand Up @@ -128,6 +169,14 @@ If you modify SCIM behavior, review impact across these areas:
5. Schema definitions and ServiceProviderConfig flags
6. Validator specs (`A1` through `A9`) and compatibility expectations

If you modify management authentication or deployment behavior, also review:

1. Both management modules' `AzureSecurityConfig` and `CloudflareSecurityConfig`
2. Shared helpers in `scim-server-common/src/main/java/.../security`
3. `docker-compose.yml` and `docker/env/*.env`
4. `k8s/app/**` and `k8s/cluster/**`
5. `.sops.yaml` and `age/rotate_sops_age_key.py`

## Adding A New SCIM Attribute

1. Extend `ScimUser`/`ScimGroup` (or add child entity in `scim-server-common` when multi-valued).
Expand Down
15 changes: 15 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,21 @@ generated/
temp/
*.tmp

# SOPS / age
*.agekey
sops-age.txt
*.decrypted.yaml
*.decrypted.yml
*.dec.yaml
*.dec.yml
/.config/sops/

# Misc
*.swp
*~

# Python bytecode
__pycache__/
*.py[cod]
# pytest cache
.pytest_cache/
4 changes: 4 additions & 0 deletions .sops.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
creation_rules:
- path_regex: ^(k8s|k8s_backup|k8s_new)/.+\.sops\.ya?ml$
encrypted_regex: "^(data|stringData)$"
age: age1j0ka5qnc6cpldfavwstqg2u6k536ymxcjeatlceraa09dgvetq9s07jkkh
Loading
Loading