Compare commits
54 Commits
hotfix/bac
...
feature/ch
| Author | SHA1 | Date | |
|---|---|---|---|
| 4641e6b319 | |||
| 97e0e48271 | |||
| df663c8193 | |||
| 612b5ffb28 | |||
| c49d03d7f7 | |||
| d47dba2ae5 | |||
| cf9eb47ecf | |||
| 3eca723f05 | |||
| f36996da11 | |||
| 6bf7db21d0 | |||
| 2641d55784 | |||
| 117297effc | |||
| fda90f9e01 | |||
| 1124377d97 | |||
| c0710b89bb | |||
| d7bda18aea | |||
| 2796e1b9d3 | |||
| d7a0c26117 | |||
| 693f2f9168 | |||
| 2509ef062c | |||
| 957757e557 | |||
| 070799da05 | |||
| 1a2817e537 | |||
| b47b0035f5 | |||
| d3fac4d43e | |||
| c37bd3ef04 | |||
| ad661ba3dd | |||
| a9625f96e6 | |||
| cb64edc927 | |||
| ac1c242fb9 | |||
| 4b29c07fd6 | |||
| 52732626e5 | |||
| 8634436dd4 | |||
| a8baa169e9 | |||
| 73ef3a6e12 | |||
| 302705d374 | |||
| f3286ef77e | |||
| 74f4f86770 | |||
| f2c56156bf | |||
| 21fb50ba00 | |||
| b90b630b06 | |||
| 66de9b8a0a | |||
| 716c552be9 | |||
| f048b47a0f | |||
| 66f40427ee | |||
| 332881cbd0 | |||
| f363afa087 | |||
| bc42347cb6 | |||
| 80d7bff4bc | |||
| 3644a3ec87 | |||
| bd478478f1 | |||
| 67b1d95509 | |||
| fff95d98a5 | |||
| 8b743efa43 |
@@ -3,7 +3,6 @@ kind: Kustomization
|
|||||||
resources:
|
resources:
|
||||||
- ../../base
|
- ../../base
|
||||||
- dbunk-demo
|
- dbunk-demo
|
||||||
- feedback
|
|
||||||
|
|
||||||
# No patches needed — base already has "upc-dev" paths
|
# No patches needed — base already has "upc-dev" paths
|
||||||
# upc-dev is the default/base cluster
|
# upc-dev is the default/base cluster
|
||||||
|
|||||||
@@ -245,12 +245,6 @@ spec:
|
|||||||
secretKeyRef:
|
secretKeyRef:
|
||||||
name: "{{ request.object.metadata.annotations.\"policies.forteapps.io/auth-oidc-credentials-secret\" || 'auth-oidc' }}"
|
name: "{{ request.object.metadata.annotations.\"policies.forteapps.io/auth-oidc-credentials-secret\" || 'auth-oidc' }}"
|
||||||
key: "{{ request.object.metadata.annotations.\"policies.forteapps.io/auth-oidc-credentials-secret-key\" || 'client-secret' }}"
|
key: "{{ request.object.metadata.annotations.\"policies.forteapps.io/auth-oidc-credentials-secret-key\" || 'client-secret' }}"
|
||||||
- name: AUTH_OIDC_IDP_HINT
|
|
||||||
value: "{{ request.object.metadata.annotations.\"policies.forteapps.io/auth-oidc-idp-hint\" || '' }}"
|
|
||||||
- name: AUTH_OIDC_BROKER_ALIAS
|
|
||||||
value: "{{ request.object.metadata.annotations.\"policies.forteapps.io/auth-oidc-broker-alias\" || '' }}"
|
|
||||||
- name: AUTH_OIDC_BROKER_TOKEN_HEADER
|
|
||||||
value: "{{ request.object.metadata.annotations.\"policies.forteapps.io/auth-oidc-broker-token-header\" || '' }}"
|
|
||||||
resources:
|
resources:
|
||||||
limits:
|
limits:
|
||||||
cpu: 50m
|
cpu: 50m
|
||||||
@@ -330,8 +324,6 @@ spec:
|
|||||||
value: "{{ request.object.metadata.annotations.\"policies.forteapps.io/auth-public-paths\" || '/healthz' }}"
|
value: "{{ request.object.metadata.annotations.\"policies.forteapps.io/auth-public-paths\" || '/healthz' }}"
|
||||||
- name: AUTH_MCP_SCOPES_SUPPORTED
|
- name: AUTH_MCP_SCOPES_SUPPORTED
|
||||||
value: "{{ request.object.metadata.annotations.\"policies.forteapps.io/auth-mcp-scopes\" || 'profile' }}"
|
value: "{{ request.object.metadata.annotations.\"policies.forteapps.io/auth-mcp-scopes\" || 'profile' }}"
|
||||||
- name: AUTH_MCP_IDP_HINT
|
|
||||||
value: "{{ request.object.metadata.annotations.\"policies.forteapps.io/auth-mcp-idp-hint\" || '' }}"
|
|
||||||
resources:
|
resources:
|
||||||
limits:
|
limits:
|
||||||
cpu: 50m
|
cpu: 50m
|
||||||
|
|||||||
@@ -1063,6 +1063,102 @@ dind:
|
|||||||
- Gitea admin panel (`/admin/runners`) — runners show as Online
|
- Gitea admin panel (`/admin/runners`) — runners show as Online
|
||||||
- Create test workflow in `.gitea/workflows/test.yml` — job executes
|
- Create test workflow in `.gitea/workflows/test.yml` — job executes
|
||||||
|
|
||||||
|
### Vaultwarden
|
||||||
|
|
||||||
|
**Chart**: `guerzon/vaultwarden`
|
||||||
|
**Version**: 0.36.4 (app v1.36.0-alpine)
|
||||||
|
**Namespace**: `vaultwarden`
|
||||||
|
|
||||||
|
**Purpose**: Self-hosted Bitwarden-compatible password manager.
|
||||||
|
|
||||||
|
**Configuration**:
|
||||||
|
```yaml
|
||||||
|
# infra/overlays/upc-dev/vaultwarden/ + infra/values/
|
||||||
|
domain: "https://bitwarden.forteapps.net"
|
||||||
|
|
||||||
|
ingress:
|
||||||
|
enabled: true
|
||||||
|
class: "traefik"
|
||||||
|
tls: true
|
||||||
|
tlsSecret: vaultwarden-tls
|
||||||
|
hostname: bitwarden.forteapps.net
|
||||||
|
additionalAnnotations:
|
||||||
|
cert-manager.io/cluster-issuer: letsencrypt-prod
|
||||||
|
|
||||||
|
database:
|
||||||
|
type: postgresql
|
||||||
|
host: vaultwarden-postgresql # StatefulSet in overlay
|
||||||
|
existingSecret: prod-db-creds
|
||||||
|
|
||||||
|
storage:
|
||||||
|
data: 5Gi (ReadWriteOnce)
|
||||||
|
attachments: 5Gi (ReadWriteOnce)
|
||||||
|
```
|
||||||
|
|
||||||
|
**TLS**: cert-manager auto-provisions Let's Encrypt certificate via `letsencrypt-prod` ClusterIssuer (same pattern as Gitea, Grafana, etc).
|
||||||
|
|
||||||
|
**SSO**: Keycloak OIDC via `forte` realm (client ID: `vaultwarden`). Self-service client config Secret (`keycloak-client-vaultwarden`) triggers registrar to create KC client and sync credentials to `vaultwarden-oidc-credentials`. PKCE enabled.
|
||||||
|
|
||||||
|
**Endpoints**:
|
||||||
|
- Web UI: `https://bitwarden.forteapps.net`
|
||||||
|
|
||||||
|
**Database**: Separate ArgoCD Application `vaultwarden-postgresql` (sync-wave `"0"`) deploys PostgreSQL 16 StatefulSet + SealedSecret before Vaultwarden (wave `"1"`). 2Gi PVC. Chart does NOT include a PostgreSQL subchart — must be provisioned separately.
|
||||||
|
|
||||||
|
**Secrets**:
|
||||||
|
- `prod-db-creds` (SealedSecret) — PostgreSQL credentials (`pgusername`, `pgpassword`) + SMTP credentials
|
||||||
|
- `vaultwarden-oidc-credentials` (registrar-managed) — OIDC client ID + secret
|
||||||
|
- `vaultwarden-tls` — auto-managed by cert-manager
|
||||||
|
|
||||||
|
### Chibisafe
|
||||||
|
|
||||||
|
**Chart**: `l4gdev/chibisafe`
|
||||||
|
**Version**: 0.1.1 (app latest)
|
||||||
|
**Namespace**: `chibisafe`
|
||||||
|
|
||||||
|
**Purpose**: Self-hosted file upload and sharing service.
|
||||||
|
|
||||||
|
**Configuration**:
|
||||||
|
```yaml
|
||||||
|
# infra/overlays/upc-dev/chibisafe/ + infra/values/
|
||||||
|
ingress:
|
||||||
|
enabled: true
|
||||||
|
className: "traefik"
|
||||||
|
hosts:
|
||||||
|
- host: chibisafe.forteapps.net
|
||||||
|
paths:
|
||||||
|
- path: /
|
||||||
|
pathType: Prefix
|
||||||
|
tls:
|
||||||
|
- secretName: chibisafe-tls
|
||||||
|
hosts:
|
||||||
|
- chibisafe.forteapps.net
|
||||||
|
|
||||||
|
persistence:
|
||||||
|
database:
|
||||||
|
enabled: true # SQLite, 1Gi
|
||||||
|
uploads:
|
||||||
|
enabled: true # User files, 10Gi
|
||||||
|
```
|
||||||
|
|
||||||
|
**Architecture**: Three-container pod — frontend (Next.js :8001), backend (API :8000), Caddy (reverse proxy :80). Auth sidecar injected via Kyverno policy (OIDC mode, port 9001).
|
||||||
|
|
||||||
|
**Ingress**: IngressRoute (not chart's built-in Ingress) targeting sidecar port 9001 directly. Chart's `ingress.enabled: false`. Separate cert-manager Certificate resource for TLS.
|
||||||
|
|
||||||
|
**Why IngressRoute**: Chart hardcodes Service `targetPort: http` → Caddy port 80. Cannot override via values. IngressRoute bypasses Service, routes directly to sidecar pod port.
|
||||||
|
|
||||||
|
**TLS**: cert-manager Certificate resource with `letsencrypt-prod` ClusterIssuer.
|
||||||
|
|
||||||
|
**Storage**: SQLite database (1Gi PVC) + uploads (10Gi PVC), both ReadWriteOnce — single replica only.
|
||||||
|
|
||||||
|
**SSO**: Keycloak OIDC via `forte` realm (client ID: `chibisafe`). Self-service client config Secret (`keycloak-client-chibisafe`) triggers registrar to create KC client and sync credentials to `chibisafe-oidc-credentials`.
|
||||||
|
|
||||||
|
**Endpoints**:
|
||||||
|
- Web UI: `https://chibisafe.forteapps.net`
|
||||||
|
|
||||||
|
**Secrets**:
|
||||||
|
- `chibisafe-tls` — auto-managed by cert-manager
|
||||||
|
- `chibisafe-oidc-credentials` (registrar-managed) — OIDC client ID + secret
|
||||||
|
|
||||||
### AI Code Review (ai-review)
|
### AI Code Review (ai-review)
|
||||||
|
|
||||||
**Type**: Gitea Actions workflow (`.gitea/workflows/ai-review.yaml`)
|
**Type**: Gitea Actions workflow (`.gitea/workflows/ai-review.yaml`)
|
||||||
@@ -1141,6 +1237,30 @@ ignore:
|
|||||||
- Check Gitea Actions tab for workflow run status and logs
|
- Check Gitea Actions tab for workflow run status and logs
|
||||||
- Monitor Anthropic usage dashboard for token consumption
|
- Monitor Anthropic usage dashboard for token consumption
|
||||||
|
|
||||||
|
### Keycloak Browser Flow (IdP Auto-Redirect)
|
||||||
|
|
||||||
|
**File**: `infra/values/base/keycloak-values.yaml` (inside `forte-realm.json`)
|
||||||
|
|
||||||
|
The realm uses a custom browser authentication flow (`browser-auto-idp`) that skips the Keycloak login page and redirects directly to the Entra ID identity provider.
|
||||||
|
|
||||||
|
**Flow executions**:
|
||||||
|
|
||||||
|
| Priority | Authenticator | Requirement | Purpose |
|
||||||
|
|----------|--------------|-------------|---------|
|
||||||
|
| 10 | `auth-cookie` | ALTERNATIVE | Reuse existing session (no redirect) |
|
||||||
|
| 20 | `identity-provider-redirector` | ALTERNATIVE | Auto-redirect to `forte-entra` IdP |
|
||||||
|
|
||||||
|
**Key fields in realm JSON**:
|
||||||
|
- `"browserFlow": "browser-auto-idp"` — overrides the default `browser` flow at realm level
|
||||||
|
- `"authenticationFlows"` — defines the custom flow with its executions
|
||||||
|
- `"authenticatorConfig"` — sets `defaultProvider: "forte-entra"` on the redirector
|
||||||
|
|
||||||
|
**Why custom flow**: The default KC browser flow shows a username/password form with an IdP button. Since all authentication is via Entra ID, the custom flow eliminates this step. The `auth-cookie` execution preserves session reuse so returning users aren't redirected again.
|
||||||
|
|
||||||
|
**Important**: The `forte-entra` identity provider must exist in Keycloak (currently configured manually in the KC admin console). If the IdP alias changes, update the `defaultProvider` value in the realm JSON.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
### Keycloak Client Registrar
|
### Keycloak Client Registrar
|
||||||
|
|
||||||
**Type**: CronJob (deployed via Keycloak Helm chart `extraDeploy`)
|
**Type**: CronJob (deployed via Keycloak Helm chart `extraDeploy`)
|
||||||
@@ -1384,46 +1504,6 @@ spec:
|
|||||||
- Adds source tracking annotations (`keycloak.forteapps.net/source-namespace`, `keycloak.forteapps.net/source-name`)
|
- Adds source tracking annotations (`keycloak.forteapps.net/source-namespace`, `keycloak.forteapps.net/source-name`)
|
||||||
- `synchronize: true` — changes to the source Secret are reflected in the clone
|
- `synchronize: true` — changes to the source Secret are reflected in the clone
|
||||||
|
|
||||||
### Keycloak Microsoft/Entra Identity Provider
|
|
||||||
|
|
||||||
**File**: `infra/values/upc-dev/keycloak-values.yaml`
|
|
||||||
**Namespace**: `keycloak`
|
|
||||||
|
|
||||||
**Purpose**: Configures Microsoft Entra (Azure AD) as an external identity provider for the Forte realm, enabling SSO via Microsoft accounts with token storage for downstream API access (e.g., Microsoft Graph).
|
|
||||||
|
|
||||||
**Configuration via keycloakConfigCli**:
|
|
||||||
- IdP alias: `forte-entra`, provider: `microsoft`
|
|
||||||
- Client secret injected from `microsoft-idp-credentials` Secret via `$(env:MS_IDP_CLIENT_SECRET)` syntax
|
|
||||||
- `extraEnvVarsSecret: microsoft-idp-credentials` makes the Secret available as env vars to config-cli
|
|
||||||
|
|
||||||
**Key Configuration Notes**:
|
|
||||||
|
|
||||||
| Field | Location | Notes |
|
|
||||||
|-------|----------|-------|
|
|
||||||
| `tenant` | `config.tenant` | **Must be `tenant`, NOT `tenantId`** — wrong key silently falls back to `common` (multi-tenant) |
|
|
||||||
| `storeToken` | Top-level IdP field | **NOT inside `config`** — enables broker token storage for KC broker API |
|
|
||||||
| `defaultScope` | `config.defaultScope` | Space-separated: `openid email profile User.Read Mail.Send` |
|
|
||||||
| `syncMode` | `config.syncMode` | `IMPORT` — imports user on first login |
|
|
||||||
|
|
||||||
**Token Storage & Broker Access**:
|
|
||||||
- `storeToken: true` persists the Entra access token in Keycloak
|
|
||||||
- Realm role `default-roles-forte` includes composite `broker.read-token` — grants all realm users access to broker token API
|
|
||||||
- Broker token retrievable via: `GET /realms/forte/broker/forte-entra/token`
|
|
||||||
|
|
||||||
**Identity Provider Mappers**:
|
|
||||||
- `forte-entra-email`: Hardcodes `emailVerified=true` for Entra-authenticated users (Entra guarantees email verification)
|
|
||||||
|
|
||||||
**Required Secret** (`microsoft-idp-credentials`):
|
|
||||||
```yaml
|
|
||||||
apiVersion: v1
|
|
||||||
kind: Secret
|
|
||||||
metadata:
|
|
||||||
name: microsoft-idp-credentials
|
|
||||||
namespace: keycloak
|
|
||||||
stringData:
|
|
||||||
MS_IDP_CLIENT_SECRET: "<entra-app-client-secret>"
|
|
||||||
```
|
|
||||||
|
|
||||||
### Default Namespace Blocker
|
### Default Namespace Blocker
|
||||||
|
|
||||||
**File**: `cluster-resources/policies/default-ns-blocker.yaml`
|
**File**: `cluster-resources/policies/default-ns-blocker.yaml`
|
||||||
|
|||||||
@@ -43,10 +43,6 @@ spec:
|
|||||||
- ServerSideApply=true
|
- ServerSideApply=true
|
||||||
|
|
||||||
ignoreDifferences:
|
ignoreDifferences:
|
||||||
- group: batch
|
|
||||||
kind: CronJob
|
|
||||||
jsonPointers:
|
|
||||||
- /spec/jobTemplate/spec/template/spec/containers/0/args
|
|
||||||
- group: apps
|
- group: apps
|
||||||
kind: StatefulSet
|
kind: StatefulSet
|
||||||
jsonPointers:
|
jsonPointers:
|
||||||
|
|||||||
8
infra/overlays/upc-dev/chibisafe/auth-oidc-secret.yaml
Normal file
8
infra/overlays/upc-dev/chibisafe/auth-oidc-secret.yaml
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
name: auth-oidc
|
||||||
|
namespace: chibisafe
|
||||||
|
type: Opaque
|
||||||
|
stringData:
|
||||||
|
cookie-secret: "gtwkoUMSp1wJa2o5Fo5CNByR8+kTocJOOuywuLexRO4="
|
||||||
43
infra/overlays/upc-dev/chibisafe/chibisafe.yaml
Normal file
43
infra/overlays/upc-dev/chibisafe/chibisafe.yaml
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
apiVersion: argoproj.io/v1alpha1
|
||||||
|
kind: Application
|
||||||
|
metadata:
|
||||||
|
name: chibisafe
|
||||||
|
namespace: argocd
|
||||||
|
annotations:
|
||||||
|
argocd.argoproj.io/sync-wave: "1"
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/name: chibisafe
|
||||||
|
app.kubernetes.io/part-of: storage
|
||||||
|
app.kubernetes.io/managed-by: argocd
|
||||||
|
finalizers:
|
||||||
|
- resources-finalizer.argocd.argoproj.io
|
||||||
|
spec:
|
||||||
|
project: default
|
||||||
|
|
||||||
|
sources:
|
||||||
|
- repoURL: https://l4gdev.github.io/helm-charts
|
||||||
|
chart: chibisafe
|
||||||
|
targetRevision: "0.1.1"
|
||||||
|
helm:
|
||||||
|
releaseName: chibisafe
|
||||||
|
valueFiles:
|
||||||
|
- $values/infra/values/base/chibisafe-values.yaml
|
||||||
|
- $values/infra/values/upc-dev/chibisafe-values.yaml
|
||||||
|
|
||||||
|
- repoURL: ssh://git@git.forteapps.net:2222/Forte/launchpad.git
|
||||||
|
targetRevision: HEAD
|
||||||
|
ref: values
|
||||||
|
|
||||||
|
destination:
|
||||||
|
server: https://kubernetes.default.svc
|
||||||
|
namespace: chibisafe
|
||||||
|
|
||||||
|
syncPolicy:
|
||||||
|
automated:
|
||||||
|
prune: true
|
||||||
|
selfHeal: true
|
||||||
|
allowEmpty: false
|
||||||
|
syncOptions:
|
||||||
|
- CreateNamespace=true
|
||||||
|
- Validate=true
|
||||||
|
- ServerSideApply=true
|
||||||
36
infra/overlays/upc-dev/chibisafe/ingressroute.yaml
Normal file
36
infra/overlays/upc-dev/chibisafe/ingressroute.yaml
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
apiVersion: cert-manager.io/v1
|
||||||
|
kind: Certificate
|
||||||
|
metadata:
|
||||||
|
name: chibisafe-tls
|
||||||
|
namespace: chibisafe
|
||||||
|
spec:
|
||||||
|
secretName: chibisafe-tls
|
||||||
|
issuerRef:
|
||||||
|
name: letsencrypt-prod
|
||||||
|
kind: ClusterIssuer
|
||||||
|
dnsNames:
|
||||||
|
- chibisafe.forteapps.net
|
||||||
|
---
|
||||||
|
apiVersion: traefik.io/v1alpha1
|
||||||
|
kind: IngressRoute
|
||||||
|
metadata:
|
||||||
|
name: chibisafe
|
||||||
|
namespace: chibisafe
|
||||||
|
annotations:
|
||||||
|
gethomepage.dev/enabled: "false"
|
||||||
|
gethomepage.dev/name: "Chibisafe"
|
||||||
|
gethomepage.dev/description: "File upload & sharing"
|
||||||
|
gethomepage.dev/group: "Storage"
|
||||||
|
gethomepage.dev/icon: "chibisafe"
|
||||||
|
gethomepage.dev/href: "https://chibisafe.forteapps.net"
|
||||||
|
spec:
|
||||||
|
entryPoints:
|
||||||
|
- websecure
|
||||||
|
routes:
|
||||||
|
- match: Host(`chibisafe.forteapps.net`)
|
||||||
|
kind: Rule
|
||||||
|
services:
|
||||||
|
- name: chibisafe
|
||||||
|
port: 9001
|
||||||
|
tls:
|
||||||
|
secretName: chibisafe-tls
|
||||||
21
infra/overlays/upc-dev/chibisafe/keycloak-client-config.yaml
Normal file
21
infra/overlays/upc-dev/chibisafe/keycloak-client-config.yaml
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
name: keycloak-client-chibisafe
|
||||||
|
namespace: chibisafe
|
||||||
|
labels:
|
||||||
|
keycloak.forteapps.net/client-config: "true"
|
||||||
|
stringData:
|
||||||
|
client.json: |
|
||||||
|
{
|
||||||
|
"clientId": "chibisafe",
|
||||||
|
"name": "Chibisafe",
|
||||||
|
"redirectUris": ["https://chibisafe.forteapps.net/*"],
|
||||||
|
"webOrigins": ["https://chibisafe.forteapps.net"],
|
||||||
|
"protocolMappers": [],
|
||||||
|
"secret": {
|
||||||
|
"namespace": "chibisafe",
|
||||||
|
"name": "chibisafe-oidc-credentials",
|
||||||
|
"keys": { "clientId": "client-id", "clientSecret": "client-secret" }
|
||||||
|
}
|
||||||
|
}
|
||||||
7
infra/overlays/upc-dev/chibisafe/kustomization.yaml
Normal file
7
infra/overlays/upc-dev/chibisafe/kustomization.yaml
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||||
|
kind: Kustomization
|
||||||
|
resources:
|
||||||
|
- chibisafe.yaml
|
||||||
|
- keycloak-client-config.yaml
|
||||||
|
- ingressroute.yaml
|
||||||
|
- auth-oidc-secret.yaml
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
---
|
|
||||||
apiVersion: bitnami.com/v1alpha1
|
|
||||||
kind: SealedSecret
|
|
||||||
metadata:
|
|
||||||
creationTimestamp: null
|
|
||||||
name: microsoft-idp-credentials
|
|
||||||
namespace: keycloak
|
|
||||||
spec:
|
|
||||||
encryptedData:
|
|
||||||
MS_IDP_CLIENT_SECRET: AgBGeloOR8LVop8yluydjc7qj4JUkb85z7B3h07i3xLPup1ojgSqtx08huv+8gvSaFoPdxOY8g23iuKeAr2b2A70paHv0ILSVRsIpxzjuao4aDRWxMHD/SFzvitvqaXD1eQUcBNRDk/1NOG0o5b9o4ddMWkNmyCYuZcmOyx18DC1kFrcWGUgJkLTr+YRZcLJ2T80obZ+y4zztYc+vNQlu11KSIALz++c9XzK2XYSdOMdFHmzadWxoCjvkJqG4W5C6AQBlYa7NSydyU6K3TnwS4VHF8w1DRNneM/IuHLMNbcL8WZjHlSS8xgXFUMhG4rkejwM6joQLx57OosTQe1/xdCOPBXq4NO8Q76RXXkoI0EYMbzfK33vr4NVh8zmBUYxhaeQySh2jYdYp7t/79UzvP7jtGYUgqIZNEBqbDKkzvXsJ4dHJnss8U8lWVgLev31ZhaTjIr3A8VKDPbJKIRZPO71/4DiCF0WKLYNKfbYJ5tsyTxivFWDY5NPNkKkgXk4QoScZ3r4bYNZjDp1rC5zCRPGf0Lt1C5Zovx1HTUjpGpAFVi7DyNmEc0uXn2sTwPARAuAj8str+RnlRNzBkpPWKdlOoDVPTSA41dSTfUVZMlQlluu4fdDgGj5sEnhEN0iIxZNRwU/2DD2AVSqG+KtdIkfH6/j0jzdFn4D3Ha6vwAsBIURK4Ird/pLuNGGCDB+LrrNGXDTTKAPFydCuRtpyoM9kFOtSZb7T7q6Vfkqa7LfgP8mdG9JGXJx
|
|
||||||
template:
|
|
||||||
metadata:
|
|
||||||
creationTimestamp: null
|
|
||||||
name: microsoft-idp-credentials
|
|
||||||
namespace: keycloak
|
|
||||||
@@ -2,7 +2,9 @@ apiVersion: kustomize.config.k8s.io/v1beta1
|
|||||||
kind: Kustomization
|
kind: Kustomization
|
||||||
resources:
|
resources:
|
||||||
- ../../base
|
- ../../base
|
||||||
- entra-upc-dev-credentials-sealed.yaml
|
- chibisafe
|
||||||
|
- vaultwarden-postgresql
|
||||||
|
- vaultwarden
|
||||||
|
|
||||||
# No patches needed — base already has "upc-dev" paths
|
# No patches needed — base already has "upc-dev" paths
|
||||||
# upc-dev is the default/base cluster
|
# upc-dev is the default/base cluster
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||||
kind: Kustomization
|
kind: Kustomization
|
||||||
resources:
|
resources:
|
||||||
- feedback.yaml
|
- vaultwarden-postgresql.yaml
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||||
|
kind: Kustomization
|
||||||
|
resources:
|
||||||
|
- postgresql.yaml
|
||||||
|
- vaultwarden-db-secret-sealed.yaml
|
||||||
@@ -0,0 +1,98 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: vaultwarden-postgresql
|
||||||
|
namespace: vaultwarden
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/name: postgresql
|
||||||
|
app.kubernetes.io/instance: vaultwarden
|
||||||
|
app.kubernetes.io/component: database
|
||||||
|
spec:
|
||||||
|
type: ClusterIP
|
||||||
|
ports:
|
||||||
|
- name: tcp-postgresql
|
||||||
|
port: 5432
|
||||||
|
targetPort: tcp-postgresql
|
||||||
|
selector:
|
||||||
|
app.kubernetes.io/name: postgresql
|
||||||
|
app.kubernetes.io/instance: vaultwarden
|
||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: StatefulSet
|
||||||
|
metadata:
|
||||||
|
name: vaultwarden-postgresql
|
||||||
|
namespace: vaultwarden
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/name: postgresql
|
||||||
|
app.kubernetes.io/instance: vaultwarden
|
||||||
|
app.kubernetes.io/component: database
|
||||||
|
spec:
|
||||||
|
serviceName: vaultwarden-postgresql
|
||||||
|
replicas: 1
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: postgresql
|
||||||
|
app.kubernetes.io/instance: vaultwarden
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/name: postgresql
|
||||||
|
app.kubernetes.io/instance: vaultwarden
|
||||||
|
app.kubernetes.io/component: database
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: postgresql
|
||||||
|
image: postgres:16-alpine
|
||||||
|
ports:
|
||||||
|
- name: tcp-postgresql
|
||||||
|
containerPort: 5432
|
||||||
|
env:
|
||||||
|
- name: POSTGRES_USER
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: prod-db-creds
|
||||||
|
key: pgusername
|
||||||
|
- name: POSTGRES_PASSWORD
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: prod-db-creds
|
||||||
|
key: pgpassword
|
||||||
|
- name: POSTGRES_DB
|
||||||
|
value: vaultwarden
|
||||||
|
- name: PGDATA
|
||||||
|
value: /var/lib/postgresql/data/pgdata
|
||||||
|
volumeMounts:
|
||||||
|
- name: data
|
||||||
|
mountPath: /var/lib/postgresql/data
|
||||||
|
livenessProbe:
|
||||||
|
exec:
|
||||||
|
command:
|
||||||
|
- sh
|
||||||
|
- -c
|
||||||
|
- pg_isready -U "$POSTGRES_USER" -d vaultwarden
|
||||||
|
initialDelaySeconds: 30
|
||||||
|
periodSeconds: 10
|
||||||
|
readinessProbe:
|
||||||
|
exec:
|
||||||
|
command:
|
||||||
|
- sh
|
||||||
|
- -c
|
||||||
|
- pg_isready -U "$POSTGRES_USER" -d vaultwarden
|
||||||
|
initialDelaySeconds: 5
|
||||||
|
periodSeconds: 5
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: 100m
|
||||||
|
memory: 256Mi
|
||||||
|
limits:
|
||||||
|
cpu: 500m
|
||||||
|
memory: 512Mi
|
||||||
|
volumeClaimTemplates:
|
||||||
|
- metadata:
|
||||||
|
name: data
|
||||||
|
spec:
|
||||||
|
accessModes:
|
||||||
|
- ReadWriteOnce
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
storage: 2Gi
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
---
|
||||||
|
apiVersion: bitnami.com/v1alpha1
|
||||||
|
kind: SealedSecret
|
||||||
|
metadata:
|
||||||
|
creationTimestamp: null
|
||||||
|
name: prod-db-creds
|
||||||
|
namespace: vaultwarden
|
||||||
|
spec:
|
||||||
|
encryptedData:
|
||||||
|
DATABASE_URL: AgAy1d//kBevUqZxB5KAXd+qxm8QykNxp5J1QP7Y30XCpE8hldPXF+NIx3w0B0PUyMAVsa+JrBmCMtzgibddIJqqF2upu/8EYxJZNusrJPOi47g3VcZIg1WyxoFfffH6jwhzv69TE/T8WGBXmWbD2vr+XWjE24Q+lgwLut0mocVfihUjpuYq0WDjgJx7pqLnY1VatTwgSkAv1uRRVqdi7e1M5isDNEpdItCbEoWwdvZhG5JIMAA/2vecY4/vEne3cg46lJAkv4ueZNATG6DOXGgQgz6h7zCKSGS1xTfGr+4A2V2/vSYpQ/r8Td37mlseoBvwN4H5O+FgHrVREm7N6aafDariYd+ZfqUIGObsZIXhxhDmAM96pjtP8ehYVwq1srWTU+SUewEmwLFWhVP1UFnTB5vgIuOWoKjHlS7dSUpStpw2u7/mQ6vhRhEaDqY6cNzJgM9hipQM/pt5an7z4ovWVeAeK8InGzKU+uxOpv/oxmi9N54B+5O4DVZC+BIbFXchxDvqivRcZrTK+CNjHjkk4We5MvN0qlhSuCYOGzEVaQ192yHciDoncw58D7fG4NicT2AcCJDVIwRGG05wqKal7g61g7Qg16oqdZIauKIU7ChSgBk7Xv33biZ4ZPe+JoSEmp9izJ8R7yyNO3KJgqH7iQ2UQzXDUqhfTr6w/oIdFST8sQtEIo7o1Z5JoXpzd4R1gVkcPWqtbbB22iRrDJsofeW+yvgGqyZLsWT2bKuDMLUn3GiqvaHaeQ9AbhNBnl6Qth3X8heBm2Zle1xxapFktisPwBQC7FDlukgvkiAOO7BywVI0+ITU4KLLOAftVqHmZ4fgDDqNFg8=
|
||||||
|
SMTP_PASSWORD: AgCbhM99+DbSTCcuxtcccOrZq99GjR51B5SkW6DNxz1jW2q4lgc6o21+gHEGGAamRDg/mWyu2UBBNgEzrW024558qP6SjVPwJclWhNZHyL4R4MCA0kv/kqNa43na2j3pq7kzT0MrqPAXD8IJrtYPxr+ngiuo7MCRef/TzEfwbwK+KgkeB1g+9ErwHWr5tU1B+3yAn5tfNeHmGFrLX230mra2ie+ntNx9kn80mb5TYoJ/mSaX7wv4bqZGEHkg7isXrMoMROXLBepCvP0zi3ta+SKJjHy73TvhKSzo7/ZHxapHw3oaazdpKJobeolWB7SziWsbXfT0gYYim3LrcieQeb7hhN3OAvSYx1Z/3UefEE1o3GFEzK1UV9ISwU/mBjMDZWyM7dK9lSbuPGvbpKU1jjP8qZWQP5v2SIT6Nb5TQgNeATdO3RkjoviqRzjJfpuu+oe5paXNeEIUSTskL7HuUjWj13DX1zDqQWTR1/Tb9ntxRtgIoAl2ymDsOednurnJeX71OJ3G++Oc8b5P2EkNQuEwaYb9raNHqZkCXeRpQVyEGIUh9sAGZUplUJSues/Jw25WuFoNBfMi/F022Mkvfnp/s0J+QrMIxSRvqiWS+7hODknvE3Zf2DI+DKClWxspfv084DAkOSV1Lq9fqNy/bKoJR/5MVHmxbW6teza6zXBnwn2nk+2DZ8IU20P15aVdtKR2zG9u8hnrqWrTQHTdvzb34WKjC0km4/MaIGKvboyw
|
||||||
|
SMTP_USERNAME: AgCijAuSvlGeMME1FyPXQdOTGKktyXfT8tjBK/ozt3X8O5hebFVvM61hNLDQTe9V/O/NLw6P1wbV4V+wtztqLs9TPDyq9L3D9JUEDjh97gWxVf7nFf8/d24F0PJoR8srKp3onb7+Rx02318RUp+gp7YsXbK6YBfkaOsoD08UgrFY3ARnP4eIirRICNCdouPgKkh038yAWcQDA20GBN2faJlQSejS4cr8WAa/ME1fRe40Q4tewgiX7hK5BWjt2eoovLrPzcHvbgTbfjwUWvmeiSicnF+VLrc3M56aKML2xuAggBk4vKtla/Af1pJfjv+Ut2z6VzECfIth12yQa6kIvKOE8aa3o/6oKLRJQRO8rQOOmLiInR+jQxrOmYw+OzkON07nBIeBon7nKYSIMiBt68kXKWJ9ZDexF7WGOHsFgUo4hA/z/c/Ccg6XHgxFt7uXZYLyziihQXy33zIsvu0rXOaczT5j3NJIhO60jz2Q8ig9JuWhd7+Dnd9EFMC0WJOM9kjpxeSjg4MYjH7VGnnEDF2GAQTlwDn5HwZJXRQFHfdCiHS5CCpfmak9MtIC9uoIsbPAnEhdTC20wDvIGlR5O4JGlQRyirKKmCdT1MJt8zi5d+EVQiicVZLGGD6nsqCNchvFYcx+glMYqWWsmyS6M+uVaYa/Fb/n+0QR6GNCF3Qi7voMJf2bFxFDk78fk76MG919XPQVAG/FPliNyWJJ7gEM+j/rDYuSrul14duV
|
||||||
|
adminToken: AgCVSgRK39WksTX6GogBvMZtPMd4XzMFkKSPhjTCm8pllzuc88pS2LXHxyGDWVLf+GZXRTCNrf5JLPst8/GTvOX17J9scRAjmhoyVVgzFNbcqGI/czLf9vH6JnhorMmUHxS+kWBm3oLZjhW3f/9vq0xzSbut87VDsyenaK4EcFLrYnfVRlMrwxL9oxPPTeB+Wah/uGoyLNfc7MMLK+/sUma4RO61VJ8YvmLUnwYNFosUcbF2B9hXMSzKKCJ+ihXYIdNIz2YWdMmj7a3D+Mor5x4jIjC+tunT4Zge5L1mx0i92KPgPkP48jKxayIZ/FxnYej+ggU6PmdYD1B6wgUbgLQV6ccwysjHce7ICvGWiM+PozFWI1qEVKqtNgp3kwInThD63Hyub9Euj0g/SE/nZcwy8DuIEhsLpLSdvxDT2lCps0VdXcb01kuta/3i4vgozSBvdIL1FrQKPLqF5+6ZEQ6BdZDkgxVqQ845WZoGbfqIyI03BMvsx/8HB5c+0Y0w0C6DRpEW55T9yRTZqzvqWUOpXy5/L2Nc9G4PCUK3lY0QPIFlPCBDl+cKgfP/XvKhMFcFpwp/Ssd0o+RhgOMBHJ5qk7RxAN1k2Y6Tkros39eUKWbM6UQ97LjrAdLcgJKX86ZkEChdeeKOnSxRmqHFXx5m4Wa6syixjipeQPwybCYQA9TgNBv0lToA7gi+lcVvXkoAgYIeB9Cp0j8UVEwdgvwWp8YgkpuWhPCAafhboH8qGhHhVfKADmlB05vUItZ0eoEVv7D9SqUTFueUmoZXwo67uyMLZhQo7eGr9+k8hiesCoEm11HCTa4DvF9zE54zgkyt0TMsKAEKmX47zJwnw76zidZC/K9e
|
||||||
|
pgpassword: AgCeQLwzajVBHW+o1ZSAcfbcJXny5K7UxxMfjud0j3hm9qx3TlLaFJrNoWd4XCuHAW1Ybl23ynWm+8kpXfZv95bXGkl0jZIm989MlAJQYKcaSTdhIM6Bkl3Cbr8kTVj2yrylGPJ96QISKNoiV7IetU82t8f21kxjyrNwt4lQEwWRFjW45jozb32qFXRkTioJ1WKaeJkyRSHWn7nLVitqZ4QjZzoN9AC7cUDOY/FffEiz7QRYSf6xaVPqQfCeH6QVtfmwtU5qNTcthOW0+/LQKpkg8i2nuoAsyOe7tsOYCENbDGkLckNTns2oPvDnH5eA8F5VDlnyJtROlwKjWfTC2zjazZynpA6cBH9XzX3Pg9P45G5HJ/4TVSUbTMCSVrbW8Ec+zdA2P4l3ytfVM2ER4N2/bQrUEVW2/ngDzhsKllmOPEN/M7b/VTed7U1xyJHsoT+AJEqVJO/vFBRxpI/ZacD+m5kWf3sp1SUWSgkUi+YWH8xuRurM2/kiUGwwUXu5ZMumjpMTkJBfX4NYRezq0DCsgaXdO2yI4xTfAysj78UikdU0PKyAXPcT8y55kJQ1jECszFauyeSYh0FpLu/XAmeB8dunlBqgISLszwnnman0/ThLeo96MFo6WPXoAeMTy8+GfTSH5tkmm8TVD7A+gRHprfFS66eY5Zi38OPU+VGRJS1J8yLSD2cNvCFR/sz1Br9VV7IySx1S+HvbEd7BwmdWrIoEcVUwIAD/U0Uxbw4sr7wLQ2wFQjDil4VItA==
|
||||||
|
pgusername: AgAcgel8GpdRVThE9i4EfFwcJYHEPnCyi4jHEaAltn4VMtub6hvhtH+ihxS97AhK6kgrTLEgtlfb07n1EZ3AK18A+ci9P5ulP0GgwMrMt1yxiHliqInvZPNb8vWC/2f2lZm7EFrBvYqMFRPV10YygtkW3Kku8h31l0xc2/DUKqZ2hMymIjx7hupabUOhnPJeF+IxVhTcsAa6SjhppX1ED0R/Im73pxTxbfLQETkHd5KcB4h6RLIPvuNiG5uftkPP8qjJqFIhNew+0IxMrsTzJbyLx90vqI6LHHtsrNDAsOHqWGnyZqIdkK+Bagm84VlpBfIdz8Fs0YqzBQaZts4+QXByzkcQZBDy11Hg9FCjdUVk3VgVLDQj+hL+aWTeJ0Iui4zW4LMSB0Dk0ZQeQa4BtwuDllky5GUA7sLmkbceAWymBNzNXSOeeAi1qfR6h6rNnh0x5yOnSN8soReNaCEYBSa8HjUamvuzu4yn+fKOJyI50QEJ7hKLXLaqyiNpa5bJw4FQvGM7qESkZW2BZLEvkq4mlKjzvSm891DozA44Zy1s/3CvytFsUtaWmquSvqqHWUxqEEemJ8zOCFXEYo1TjEfkYIUipM5KJ+PrpQGTgjdnL8FbAv3r3NG7DoucQtVeJJVeaBqOZcfEQw4Xz15grsdjggFunhmz+ZjWjgEwV4G/dCmeus3SBWJWLMOoPWCvBWrQZRQq9KVj
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
creationTimestamp: null
|
||||||
|
name: prod-db-creds
|
||||||
|
namespace: vaultwarden
|
||||||
@@ -1,34 +1,33 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Namespace
|
||||||
|
metadata:
|
||||||
|
name: vaultwarden
|
||||||
|
---
|
||||||
|
|
||||||
apiVersion: argoproj.io/v1alpha1
|
apiVersion: argoproj.io/v1alpha1
|
||||||
kind: Application
|
kind: Application
|
||||||
metadata:
|
metadata:
|
||||||
name: feedback
|
name: vaultwarden-postgresql
|
||||||
namespace: argocd
|
namespace: argocd
|
||||||
annotations:
|
annotations:
|
||||||
argocd.argoproj.io/sync-wave: "12"
|
argocd.argoproj.io/sync-wave: "0"
|
||||||
labels:
|
labels:
|
||||||
app.kubernetes.io/name: feedback
|
app.kubernetes.io/name: vaultwarden-postgresql
|
||||||
app.kubernetes.io/part-of: apps
|
app.kubernetes.io/part-of: security
|
||||||
app.kubernetes.io/managed-by: argocd
|
app.kubernetes.io/managed-by: argocd
|
||||||
finalizers:
|
finalizers:
|
||||||
- resources-finalizer.argocd.argoproj.io
|
- resources-finalizer.argocd.argoproj.io
|
||||||
spec:
|
spec:
|
||||||
project: default
|
project: default
|
||||||
|
|
||||||
sources:
|
source:
|
||||||
- repoURL: ssh://git@git.forteapps.net:2222/Forte/forte-helm.git
|
repoURL: ssh://git@git.forteapps.net:2222/Forte/launchpad.git
|
||||||
path: forteapp
|
|
||||||
targetRevision: HEAD
|
targetRevision: HEAD
|
||||||
helm:
|
path: infra/overlays/upc-dev/vaultwarden-postgresql/resources
|
||||||
valueFiles:
|
|
||||||
- $values/feedback/values.yaml
|
|
||||||
|
|
||||||
- repoURL: ssh://git@git.forteapps.net:2222/Forte/helm-prod-values.git
|
|
||||||
targetRevision: HEAD
|
|
||||||
ref: values
|
|
||||||
|
|
||||||
destination:
|
destination:
|
||||||
server: https://kubernetes.default.svc
|
server: https://kubernetes.default.svc
|
||||||
namespace: feedback
|
namespace: vaultwarden
|
||||||
|
|
||||||
syncPolicy:
|
syncPolicy:
|
||||||
automated:
|
automated:
|
||||||
@@ -39,12 +38,6 @@ spec:
|
|||||||
- CreateNamespace=true
|
- CreateNamespace=true
|
||||||
- Validate=true
|
- Validate=true
|
||||||
- ServerSideApply=true
|
- ServerSideApply=true
|
||||||
retry:
|
|
||||||
limit: 5
|
|
||||||
backoff:
|
|
||||||
duration: 5s
|
|
||||||
factor: 2
|
|
||||||
maxDuration: 3m
|
|
||||||
|
|
||||||
ignoreDifferences:
|
ignoreDifferences:
|
||||||
- group: apps
|
- group: apps
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
name: keycloak-client-vaultwarden
|
||||||
|
namespace: vaultwarden
|
||||||
|
labels:
|
||||||
|
keycloak.forteapps.net/client-config: "true"
|
||||||
|
stringData:
|
||||||
|
client.json: |
|
||||||
|
{
|
||||||
|
"clientId": "vaultwarden",
|
||||||
|
"name": "Vaultwarden",
|
||||||
|
"redirectUris": ["https://vaultwarden.forteapps.net/*"],
|
||||||
|
"webOrigins": ["https://vaultwarden.forteapps.net"],
|
||||||
|
"protocolMappers": [],
|
||||||
|
"secret": {
|
||||||
|
"namespace": "vaultwarden",
|
||||||
|
"name": "vaultwarden-oidc-credentials",
|
||||||
|
"keys": { "clientId": "client-id", "clientSecret": "client-secret" }
|
||||||
|
}
|
||||||
|
}
|
||||||
5
infra/overlays/upc-dev/vaultwarden/kustomization.yaml
Normal file
5
infra/overlays/upc-dev/vaultwarden/kustomization.yaml
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||||
|
kind: Kustomization
|
||||||
|
resources:
|
||||||
|
- vaultwarden.yaml
|
||||||
|
- keycloak-client-config.yaml
|
||||||
43
infra/overlays/upc-dev/vaultwarden/vaultwarden.yaml
Normal file
43
infra/overlays/upc-dev/vaultwarden/vaultwarden.yaml
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
apiVersion: argoproj.io/v1alpha1
|
||||||
|
kind: Application
|
||||||
|
metadata:
|
||||||
|
name: vaultwarden
|
||||||
|
namespace: argocd
|
||||||
|
annotations:
|
||||||
|
argocd.argoproj.io/sync-wave: "1"
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/name: vaultwarden
|
||||||
|
app.kubernetes.io/part-of: security
|
||||||
|
app.kubernetes.io/managed-by: argocd
|
||||||
|
finalizers:
|
||||||
|
- resources-finalizer.argocd.argoproj.io
|
||||||
|
spec:
|
||||||
|
project: default
|
||||||
|
|
||||||
|
sources:
|
||||||
|
- repoURL: https://guerzon.github.io/vaultwarden
|
||||||
|
chart: vaultwarden
|
||||||
|
targetRevision: "0.36.4"
|
||||||
|
helm:
|
||||||
|
releaseName: vaultwarden
|
||||||
|
valueFiles:
|
||||||
|
- $values/infra/values/base/vaultwarden-values.yaml
|
||||||
|
- $values/infra/values/upc-dev/vaultwarden-values.yaml
|
||||||
|
|
||||||
|
- repoURL: ssh://git@git.forteapps.net:2222/Forte/launchpad.git
|
||||||
|
targetRevision: HEAD
|
||||||
|
ref: values
|
||||||
|
|
||||||
|
destination:
|
||||||
|
server: https://kubernetes.default.svc
|
||||||
|
namespace: vaultwarden
|
||||||
|
|
||||||
|
syncPolicy:
|
||||||
|
automated:
|
||||||
|
prune: true
|
||||||
|
selfHeal: true
|
||||||
|
allowEmpty: false
|
||||||
|
syncOptions:
|
||||||
|
- CreateNamespace=true
|
||||||
|
- Validate=true
|
||||||
|
- ServerSideApply=true
|
||||||
45
infra/values/base/chibisafe-values.yaml
Normal file
45
infra/values/base/chibisafe-values.yaml
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
replicaCount: 1
|
||||||
|
|
||||||
|
frontend:
|
||||||
|
image:
|
||||||
|
repository: chibisafe/chibisafe
|
||||||
|
tag: "latest"
|
||||||
|
pullPolicy: IfNotPresent
|
||||||
|
|
||||||
|
backend:
|
||||||
|
image:
|
||||||
|
repository: chibisafe/chibisafe-server
|
||||||
|
tag: "latest"
|
||||||
|
pullPolicy: IfNotPresent
|
||||||
|
|
||||||
|
caddy:
|
||||||
|
image:
|
||||||
|
repository: caddy
|
||||||
|
tag: "2-alpine"
|
||||||
|
pullPolicy: IfNotPresent
|
||||||
|
|
||||||
|
persistence:
|
||||||
|
database:
|
||||||
|
enabled: true
|
||||||
|
size: 1Gi
|
||||||
|
accessModes:
|
||||||
|
- ReadWriteOnce
|
||||||
|
|
||||||
|
uploads:
|
||||||
|
enabled: true
|
||||||
|
size: 10Gi
|
||||||
|
accessModes:
|
||||||
|
- ReadWriteOnce
|
||||||
|
|
||||||
|
logs:
|
||||||
|
enabled: false
|
||||||
|
|
||||||
|
service:
|
||||||
|
type: ClusterIP
|
||||||
|
port: 80
|
||||||
|
|
||||||
|
networkPolicy:
|
||||||
|
enabled: false
|
||||||
|
|
||||||
|
podDisruptionBudget:
|
||||||
|
enabled: false
|
||||||
@@ -41,6 +41,7 @@ gitea:
|
|||||||
oauth2:
|
oauth2:
|
||||||
ENABLED: true
|
ENABLED: true
|
||||||
ENABLE_AUTO_REGISTRATION: true
|
ENABLE_AUTO_REGISTRATION: true
|
||||||
|
ACCOUNT_LINKING: auto
|
||||||
USERNAME: email
|
USERNAME: email
|
||||||
|
|
||||||
session:
|
session:
|
||||||
|
|||||||
@@ -58,6 +58,9 @@ keycloakConfigCli:
|
|||||||
enabled: true
|
enabled: true
|
||||||
image:
|
image:
|
||||||
repository: bitnamilegacy/keycloak-config-cli
|
repository: bitnamilegacy/keycloak-config-cli
|
||||||
|
extraEnvVars:
|
||||||
|
- name: IMPORT_MANAGED_PROTOCOL_MAPPER
|
||||||
|
value: "no-delete"
|
||||||
configuration:
|
configuration:
|
||||||
forte-realm.json: |
|
forte-realm.json: |
|
||||||
{
|
{
|
||||||
@@ -101,6 +104,18 @@ keycloakConfigCli:
|
|||||||
"access.token.claim": "true",
|
"access.token.claim": "true",
|
||||||
"userinfo.token.claim": "true"
|
"userinfo.token.claim": "true"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "groups",
|
||||||
|
"protocol": "openid-connect",
|
||||||
|
"protocolMapper": "oidc-group-membership-mapper",
|
||||||
|
"config": {
|
||||||
|
"claim.name": "groups",
|
||||||
|
"full.path": "false",
|
||||||
|
"id.token.claim": "true",
|
||||||
|
"access.token.claim": "true",
|
||||||
|
"userinfo.token.claim": "true"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -173,7 +188,54 @@ keycloakConfigCli:
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"browserFlow": "browser-auto-idp",
|
||||||
|
"authenticationFlows": [
|
||||||
|
{
|
||||||
|
"alias": "browser-auto-idp",
|
||||||
|
"description": "Browser flow with auto-redirect to Forte Entra IdP",
|
||||||
|
"providerId": "basic-flow",
|
||||||
|
"topLevel": true,
|
||||||
|
"builtIn": false,
|
||||||
|
"authenticationExecutions": [
|
||||||
|
{
|
||||||
|
"authenticator": "auth-cookie",
|
||||||
|
"authenticatorFlow": false,
|
||||||
|
"requirement": "ALTERNATIVE",
|
||||||
|
"priority": 10
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"authenticator": "identity-provider-redirector",
|
||||||
|
"authenticatorFlow": false,
|
||||||
|
"requirement": "ALTERNATIVE",
|
||||||
|
"priority": 20,
|
||||||
|
"authenticatorConfig": "forte-entra-redirector"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"authenticatorConfig": [
|
||||||
|
{
|
||||||
|
"alias": "forte-entra-redirector",
|
||||||
|
"config": {
|
||||||
|
"defaultProvider": "forte-entra"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
"groups": [
|
"groups": [
|
||||||
|
{
|
||||||
|
"name": "k8s",
|
||||||
|
"path": "/k8s",
|
||||||
|
"clientRoles": {
|
||||||
|
"grafana": ["Editor"]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "dev",
|
||||||
|
"path": "/dev",
|
||||||
|
"clientRoles": {
|
||||||
|
"grafana": ["Viewer"]
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "ArgoCD Admins",
|
"name": "ArgoCD Admins",
|
||||||
"path": "/ArgoCD Admins"
|
"path": "/ArgoCD Admins"
|
||||||
@@ -259,7 +321,7 @@ extraDeploy:
|
|||||||
ADMIN_PASS=$(cat /secrets/admin-password)
|
ADMIN_PASS=$(cat /secrets/admin-password)
|
||||||
|
|
||||||
echo "Authenticating to Keycloak..."
|
echo "Authenticating to Keycloak..."
|
||||||
TOKEN=$(curl -s -X POST "${KEYCLOAK_URL}/realms/master/protocol/openid-connect/token" \
|
TOKEN=$(curl -sf -X POST "${KEYCLOAK_URL}/realms/master/protocol/openid-connect/token" \
|
||||||
-d "client_id=admin-cli" \
|
-d "client_id=admin-cli" \
|
||||||
-d "username=${ADMIN_USER}" \
|
-d "username=${ADMIN_USER}" \
|
||||||
-d "password=${ADMIN_PASS}" \
|
-d "password=${ADMIN_PASS}" \
|
||||||
@@ -276,7 +338,7 @@ extraDeploy:
|
|||||||
upsert_secret() {
|
upsert_secret() {
|
||||||
local ns="$1" name="$2" manifest="$3"
|
local ns="$1" name="$2" manifest="$3"
|
||||||
local code
|
local code
|
||||||
code=$(curl -s -o /dev/null -w "%{http_code}" \
|
code=$(curl -sf -o /dev/null -w "%{http_code}" \
|
||||||
--cacert "$CA_CERT" \
|
--cacert "$CA_CERT" \
|
||||||
-H "Authorization: Bearer ${SA_TOKEN}" \
|
-H "Authorization: Bearer ${SA_TOKEN}" \
|
||||||
-H "Content-Type: application/json" \
|
-H "Content-Type: application/json" \
|
||||||
@@ -285,7 +347,7 @@ extraDeploy:
|
|||||||
if [ "$code" = "200" ]; then
|
if [ "$code" = "200" ]; then
|
||||||
echo " Updated secret '${ns}/${name}'"
|
echo " Updated secret '${ns}/${name}'"
|
||||||
elif [ "$code" = "404" ]; then
|
elif [ "$code" = "404" ]; then
|
||||||
code=$(curl -s -o /dev/null -w "%{http_code}" \
|
code=$(curl -sf -o /dev/null -w "%{http_code}" \
|
||||||
--cacert "$CA_CERT" \
|
--cacert "$CA_CERT" \
|
||||||
-H "Authorization: Bearer ${SA_TOKEN}" \
|
-H "Authorization: Bearer ${SA_TOKEN}" \
|
||||||
-H "Content-Type: application/json" \
|
-H "Content-Type: application/json" \
|
||||||
@@ -332,7 +394,7 @@ extraDeploy:
|
|||||||
|
|
||||||
# Get the client secret from Keycloak
|
# Get the client secret from Keycloak
|
||||||
local secret_value
|
local secret_value
|
||||||
secret_value=$(curl -s -H "Authorization: Bearer ${TOKEN}" \
|
secret_value=$(curl -sf -H "Authorization: Bearer ${TOKEN}" \
|
||||||
"${KEYCLOAK_URL}/admin/realms/${REALM}/clients/${client_uuid}/client-secret" \
|
"${KEYCLOAK_URL}/admin/realms/${REALM}/clients/${client_uuid}/client-secret" \
|
||||||
| jq -r '.value')
|
| jq -r '.value')
|
||||||
|
|
||||||
@@ -347,7 +409,7 @@ extraDeploy:
|
|||||||
|
|
||||||
# Write to target namespace (if it exists)
|
# Write to target namespace (if it exists)
|
||||||
local ns_status
|
local ns_status
|
||||||
ns_status=$(curl -s -o /dev/null -w "%{http_code}" \
|
ns_status=$(curl -sf -o /dev/null -w "%{http_code}" \
|
||||||
--cacert "$CA_CERT" \
|
--cacert "$CA_CERT" \
|
||||||
-H "Authorization: Bearer ${SA_TOKEN}" \
|
-H "Authorization: Bearer ${SA_TOKEN}" \
|
||||||
"${K8S_API}/api/v1/namespaces/${target_ns}")
|
"${K8S_API}/api/v1/namespaces/${target_ns}")
|
||||||
@@ -371,12 +433,12 @@ extraDeploy:
|
|||||||
local ns="$1" name="$2" key="$3" value="$4"
|
local ns="$1" name="$2" key="$3" value="$4"
|
||||||
local patch
|
local patch
|
||||||
patch=$(printf '{"metadata":{"annotations":{"%s":"%s"}}}' "$key" "$value")
|
patch=$(printf '{"metadata":{"annotations":{"%s":"%s"}}}' "$key" "$value")
|
||||||
curl -s -o /dev/null \
|
curl -sf -o /dev/null \
|
||||||
--cacert "$CA_CERT" \
|
--cacert "$CA_CERT" \
|
||||||
-H "Authorization: Bearer ${SA_TOKEN}" \
|
-H "Authorization: Bearer ${SA_TOKEN}" \
|
||||||
-H "Content-Type: application/strategic-merge-patch+json" \
|
-H "Content-Type: application/strategic-merge-patch+json" \
|
||||||
-X PATCH -d "$patch" \
|
-X PATCH -d "$patch" \
|
||||||
"${K8S_API}/api/v1/namespaces/${ns}/secrets/${name}" || true
|
"${K8S_API}/api/v1/namespaces/${ns}/secrets/${name}"
|
||||||
}
|
}
|
||||||
|
|
||||||
# =============================================
|
# =============================================
|
||||||
@@ -384,7 +446,7 @@ extraDeploy:
|
|||||||
# =============================================
|
# =============================================
|
||||||
echo "=== Legacy sync: clients with k8s.secret.sync=true ==="
|
echo "=== Legacy sync: clients with k8s.secret.sync=true ==="
|
||||||
|
|
||||||
CLIENTS=$(curl -s -H "Authorization: Bearer ${TOKEN}" \
|
CLIENTS=$(curl -sf -H "Authorization: Bearer ${TOKEN}" \
|
||||||
"${KEYCLOAK_URL}/admin/realms/${REALM}/clients")
|
"${KEYCLOAK_URL}/admin/realms/${REALM}/clients")
|
||||||
|
|
||||||
SYNC_CLIENTS=$(echo "$CLIENTS" | jq -c '[.[] | select(.attributes["k8s.secret.sync"] == "true")]')
|
SYNC_CLIENTS=$(echo "$CLIENTS" | jq -c '[.[] | select(.attributes["k8s.secret.sync"] == "true")]')
|
||||||
@@ -409,7 +471,7 @@ extraDeploy:
|
|||||||
echo ""
|
echo ""
|
||||||
echo "=== Self-service: config Secrets with label keycloak.forteapps.net/client-config=true ==="
|
echo "=== Self-service: config Secrets with label keycloak.forteapps.net/client-config=true ==="
|
||||||
|
|
||||||
CONFIG_SECRETS=$(curl -s \
|
CONFIG_SECRETS=$(curl -sf \
|
||||||
--cacert "$CA_CERT" \
|
--cacert "$CA_CERT" \
|
||||||
-H "Authorization: Bearer ${SA_TOKEN}" \
|
-H "Authorization: Bearer ${SA_TOKEN}" \
|
||||||
"${K8S_API}/api/v1/namespaces/keycloak/secrets?labelSelector=keycloak.forteapps.net/client-config=true")
|
"${K8S_API}/api/v1/namespaces/keycloak/secrets?labelSelector=keycloak.forteapps.net/client-config=true")
|
||||||
@@ -430,10 +492,6 @@ extraDeploy:
|
|||||||
CLIENT_JSON=$(printf '%s' "$CLIENT_JSON_B64" | base64 -d)
|
CLIENT_JSON=$(printf '%s' "$CLIENT_JSON_B64" | base64 -d)
|
||||||
|
|
||||||
CLIENT_ID=$(echo "$CLIENT_JSON" | jq -r '.clientId')
|
CLIENT_ID=$(echo "$CLIENT_JSON" | jq -r '.clientId')
|
||||||
if [ -z "$CLIENT_ID" ] || [ "$CLIENT_ID" = "null" ]; then
|
|
||||||
echo "ERROR: Could not extract clientId from config '${CONFIG_NAME}', skipping"
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
echo "Processing self-service client '${CLIENT_ID}' from config '${CONFIG_NAME}'"
|
echo "Processing self-service client '${CLIENT_ID}' from config '${CONFIG_NAME}'"
|
||||||
|
|
||||||
# Compute config hash for change detection
|
# Compute config hash for change detection
|
||||||
@@ -450,7 +508,7 @@ extraDeploy:
|
|||||||
CRED_EXISTS=$(curl -s -o /dev/null -w "%{http_code}" \
|
CRED_EXISTS=$(curl -s -o /dev/null -w "%{http_code}" \
|
||||||
--cacert "$CA_CERT" \
|
--cacert "$CA_CERT" \
|
||||||
-H "Authorization: Bearer ${SA_TOKEN}" \
|
-H "Authorization: Bearer ${SA_TOKEN}" \
|
||||||
"${K8S_API}/api/v1/namespaces/${CRED_NS}/secrets/${CRED_NAME}")
|
"${K8S_API}/api/v1/namespaces/${CRED_NS}/secrets/${CRED_NAME}" || echo "000")
|
||||||
|
|
||||||
# Skip if hash matches and credential Secret exists
|
# Skip if hash matches and credential Secret exists
|
||||||
if [ "$CONFIG_HASH" = "$EXISTING_HASH" ] && [ "$CRED_EXISTS" = "200" ]; then
|
if [ "$CONFIG_HASH" = "$EXISTING_HASH" ] && [ "$CRED_EXISTS" = "200" ]; then
|
||||||
@@ -471,68 +529,46 @@ extraDeploy:
|
|||||||
redirectUris: .redirectUris,
|
redirectUris: .redirectUris,
|
||||||
webOrigins: .webOrigins,
|
webOrigins: .webOrigins,
|
||||||
protocolMappers: (.protocolMappers // [])
|
protocolMappers: (.protocolMappers // [])
|
||||||
} + if .defaultClientScopes then {defaultClientScopes: .defaultClientScopes} else {} end')
|
} | with_entries(select(.value != null))')
|
||||||
|
|
||||||
# Check if client already exists
|
# Check if client already exists
|
||||||
EXISTING=$(curl -s -H "Authorization: Bearer ${TOKEN}" \
|
EXISTING_RESPONSE=$(curl -s -H "Authorization: Bearer ${TOKEN}" \
|
||||||
"${KEYCLOAK_URL}/admin/realms/${REALM}/clients?clientId=${CLIENT_ID}" \
|
"${KEYCLOAK_URL}/admin/realms/${REALM}/clients?clientId=${CLIENT_ID}" || true)
|
||||||
| jq -r '.[0].id // empty')
|
EXISTING=$(echo "$EXISTING_RESPONSE" | jq -r '.[0].id // empty' 2>/dev/null || true)
|
||||||
|
|
||||||
if [ -n "$EXISTING" ]; then
|
if [ -n "$EXISTING" ]; then
|
||||||
echo " Updating existing Keycloak client (uuid: ${EXISTING})"
|
echo " Updating existing Keycloak client (uuid: ${EXISTING})"
|
||||||
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" \
|
RESPONSE=$(curl -s -w "\n%{http_code}" \
|
||||||
-H "Authorization: Bearer ${TOKEN}" \
|
-H "Authorization: Bearer ${TOKEN}" \
|
||||||
-H "Content-Type: application/json" \
|
-H "Content-Type: application/json" \
|
||||||
-X PUT -d "$KC_CLIENT" \
|
-X PUT -d "$KC_CLIENT" \
|
||||||
"${KEYCLOAK_URL}/admin/realms/${REALM}/clients/${EXISTING}")
|
"${KEYCLOAK_URL}/admin/realms/${REALM}/clients/${EXISTING}" || true)
|
||||||
|
HTTP_CODE=$(echo "$RESPONSE" | tail -1)
|
||||||
|
RESPONSE_BODY=$(echo "$RESPONSE" | sed '$d')
|
||||||
if [ "$HTTP_CODE" != "204" ] && [ "$HTTP_CODE" != "200" ]; then
|
if [ "$HTTP_CODE" != "204" ] && [ "$HTTP_CODE" != "200" ]; then
|
||||||
echo " ERROR: Failed to update client '${CLIENT_ID}' (HTTP ${HTTP_CODE})"
|
echo " ERROR: Failed to update client '${CLIENT_ID}' (HTTP ${HTTP_CODE}): ${RESPONSE_BODY}"
|
||||||
annotate_secret "keycloak" "$CONFIG_NAME" "keycloak.forteapps.net/sync-status" "error"
|
annotate_secret "keycloak" "$CONFIG_NAME" "keycloak.forteapps.net/sync-status" "error"
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
CLIENT_UUID="$EXISTING"
|
CLIENT_UUID="$EXISTING"
|
||||||
else
|
else
|
||||||
echo " Creating new Keycloak client '${CLIENT_ID}'"
|
echo " Creating new Keycloak client '${CLIENT_ID}'"
|
||||||
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" \
|
RESPONSE=$(curl -s -w "\n%{http_code}" \
|
||||||
-H "Authorization: Bearer ${TOKEN}" \
|
-H "Authorization: Bearer ${TOKEN}" \
|
||||||
-H "Content-Type: application/json" \
|
-H "Content-Type: application/json" \
|
||||||
-X POST -d "$KC_CLIENT" \
|
-X POST -d "$KC_CLIENT" \
|
||||||
"${KEYCLOAK_URL}/admin/realms/${REALM}/clients")
|
"${KEYCLOAK_URL}/admin/realms/${REALM}/clients" || true)
|
||||||
|
HTTP_CODE=$(echo "$RESPONSE" | tail -1)
|
||||||
|
RESPONSE_BODY=$(echo "$RESPONSE" | sed '$d')
|
||||||
if [ "$HTTP_CODE" != "201" ]; then
|
if [ "$HTTP_CODE" != "201" ]; then
|
||||||
echo " ERROR: Failed to create client '${CLIENT_ID}' (HTTP ${HTTP_CODE})"
|
echo " ERROR: Failed to create client '${CLIENT_ID}' (HTTP ${HTTP_CODE}): ${RESPONSE_BODY}"
|
||||||
annotate_secret "keycloak" "$CONFIG_NAME" "keycloak.forteapps.net/sync-status" "error"
|
annotate_secret "keycloak" "$CONFIG_NAME" "keycloak.forteapps.net/sync-status" "error"
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
# Fetch the newly created client's UUID
|
# Fetch the newly created client's UUID
|
||||||
CLIENT_UUID=$(curl -s -H "Authorization: Bearer ${TOKEN}" \
|
CLIENT_UUID=$(curl -s -H "Authorization: Bearer ${TOKEN}" \
|
||||||
"${KEYCLOAK_URL}/admin/realms/${REALM}/clients?clientId=${CLIENT_ID}" \
|
"${KEYCLOAK_URL}/admin/realms/${REALM}/clients?clientId=${CLIENT_ID}" \
|
||||||
| jq -r '.[0].id')
|
| jq -r '.[0].id' || true)
|
||||||
fi
|
|
||||||
|
|
||||||
# Assign default client scopes (KC REST API ignores defaultClientScopes in POST/PUT body)
|
|
||||||
REQUESTED_SCOPES=$(echo "$CLIENT_JSON" | jq -r '.defaultClientScopes // [] | .[]' 2>/dev/null)
|
|
||||||
if [ -n "$REQUESTED_SCOPES" ]; then
|
|
||||||
# Fetch all realm client scopes once
|
|
||||||
ALL_SCOPES=$(curl -s -H "Authorization: Bearer ${TOKEN}" \
|
|
||||||
"${KEYCLOAK_URL}/admin/realms/${REALM}/client-scopes")
|
|
||||||
|
|
||||||
echo "$REQUESTED_SCOPES" | while read -r SCOPE_NAME; do
|
|
||||||
[ -z "$SCOPE_NAME" ] && continue
|
|
||||||
SCOPE_ID=$(echo "$ALL_SCOPES" | jq -r --arg name "$SCOPE_NAME" '.[] | select(.name == $name) | .id // empty')
|
|
||||||
if [ -z "$SCOPE_ID" ]; then
|
|
||||||
echo " WARNING: Scope '${SCOPE_NAME}' not found in realm, skipping"
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
SC_CODE=$(curl -s -o /dev/null -w "%{http_code}" \
|
|
||||||
-H "Authorization: Bearer ${TOKEN}" \
|
|
||||||
-X PUT \
|
|
||||||
"${KEYCLOAK_URL}/admin/realms/${REALM}/clients/${CLIENT_UUID}/default-client-scopes/${SCOPE_ID}")
|
|
||||||
if [ "$SC_CODE" = "204" ] || [ "$SC_CODE" = "200" ]; then
|
|
||||||
echo " Assigned scope '${SCOPE_NAME}'"
|
|
||||||
else
|
|
||||||
echo " WARNING: Failed to assign scope '${SCOPE_NAME}' (HTTP ${SC_CODE})"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Sync credentials to target namespace
|
# Sync credentials to target namespace
|
||||||
|
|||||||
3
infra/values/base/vaultwarden-values.yaml
Normal file
3
infra/values/base/vaultwarden-values.yaml
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
image:
|
||||||
|
tag: "1.36.0-alpine"
|
||||||
|
domain: "https://vaultwarden.forteapps.net"
|
||||||
11
infra/values/upc-dev/chibisafe-values.yaml
Normal file
11
infra/values/upc-dev/chibisafe-values.yaml
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
podAnnotations:
|
||||||
|
policies.forteapps.io/auth: "true"
|
||||||
|
policies.forteapps.io/auth-type: "oidc"
|
||||||
|
policies.forteapps.io/auth-oidc-authority: "https://id.forteapps.net/realms/forte"
|
||||||
|
policies.forteapps.io/auth-oidc-client-id: "chibisafe"
|
||||||
|
policies.forteapps.io/auth-oidc-callback-path: "https://chibisafe.forteapps.net/auth/callback"
|
||||||
|
policies.forteapps.io/auth-oidc-credentials-secret: "chibisafe-oidc-credentials"
|
||||||
|
|
||||||
|
# Ingress disabled — using IngressRoute to target sidecar port directly
|
||||||
|
ingress:
|
||||||
|
enabled: false
|
||||||
@@ -1,112 +1,2 @@
|
|||||||
ingress:
|
ingress:
|
||||||
hostname: id.forteapps.net
|
hostname: id.forteapps.net
|
||||||
|
|
||||||
extraEnvVars:
|
|
||||||
- name: KC_FEATURES
|
|
||||||
value: "token-exchange:v1,admin-fine-grained-authz:v1"
|
|
||||||
|
|
||||||
keycloakConfigCli:
|
|
||||||
enabled: true
|
|
||||||
extraEnvVars:
|
|
||||||
- name: IMPORT_VAR_SUBSTITUTION_ENABLED
|
|
||||||
value: "true"
|
|
||||||
- name: MS_IDP_CLIENT_SECRET
|
|
||||||
valueFrom:
|
|
||||||
secretKeyRef:
|
|
||||||
name: microsoft-idp-credentials
|
|
||||||
key: MS_IDP_CLIENT_SECRET
|
|
||||||
configuration:
|
|
||||||
microsoft-idp.json: |
|
|
||||||
{
|
|
||||||
"realm": "forte",
|
|
||||||
"authenticationFlows": [
|
|
||||||
{
|
|
||||||
"alias": "auto-link-first-broker-login",
|
|
||||||
"description": "Auto-link IdP accounts to existing users by email",
|
|
||||||
"providerId": "basic-flow",
|
|
||||||
"topLevel": true,
|
|
||||||
"builtIn": false,
|
|
||||||
"authenticationExecutions": [
|
|
||||||
{
|
|
||||||
"authenticator": "idp-create-user-if-unique",
|
|
||||||
"authenticatorFlow": false,
|
|
||||||
"requirement": "ALTERNATIVE",
|
|
||||||
"priority": 10
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"authenticator": "idp-auto-link",
|
|
||||||
"authenticatorFlow": false,
|
|
||||||
"requirement": "ALTERNATIVE",
|
|
||||||
"priority": 20
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"identityProviders": [
|
|
||||||
{
|
|
||||||
"alias": "forte-entra",
|
|
||||||
"displayName": "Forte Entra",
|
|
||||||
"providerId": "microsoft",
|
|
||||||
"enabled": true,
|
|
||||||
"trustEmail": true,
|
|
||||||
"firstBrokerLoginFlowAlias": "auto-link-first-broker-login",
|
|
||||||
"config": {
|
|
||||||
"clientId": "7995d2b5-b798-4caf-8da6-b00b78bb34d7",
|
|
||||||
"clientSecret": "$(env:MS_IDP_CLIENT_SECRET)",
|
|
||||||
"defaultScope": "openid email profile",
|
|
||||||
"tenantId": "063afd9e-5fcb-48d2-a769-ca31b0f5b443",
|
|
||||||
"syncMode": "IMPORT"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"alias": "forte-entra-graph",
|
|
||||||
"displayName": "Forte Entra (Graph)",
|
|
||||||
"providerId": "microsoft",
|
|
||||||
"enabled": true,
|
|
||||||
"storeToken": true,
|
|
||||||
"trustEmail": true,
|
|
||||||
"firstBrokerLoginFlowAlias": "auto-link-first-broker-login",
|
|
||||||
"config": {
|
|
||||||
"clientId": "7995d2b5-b798-4caf-8da6-b00b78bb34d7",
|
|
||||||
"clientSecret": "$(env:MS_IDP_CLIENT_SECRET)",
|
|
||||||
"defaultScope": "openid email profile User.Read Mail.Send",
|
|
||||||
"tenantId": "063afd9e-5fcb-48d2-a769-ca31b0f5b443",
|
|
||||||
"syncMode": "IMPORT"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"identityProviderMappers": [
|
|
||||||
{
|
|
||||||
"name": "forte-entra-email",
|
|
||||||
"identityProviderAlias": "forte-entra",
|
|
||||||
"identityProviderMapper": "hardcoded-attribute-idp-mapper",
|
|
||||||
"config": {
|
|
||||||
"syncMode": "INHERIT",
|
|
||||||
"attribute": "emailVerified",
|
|
||||||
"attribute.value": "true"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "forte-entra-graph-email",
|
|
||||||
"identityProviderAlias": "forte-entra-graph",
|
|
||||||
"identityProviderMapper": "hardcoded-attribute-idp-mapper",
|
|
||||||
"config": {
|
|
||||||
"syncMode": "INHERIT",
|
|
||||||
"attribute": "emailVerified",
|
|
||||||
"attribute.value": "true"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"roles": {
|
|
||||||
"realm": [
|
|
||||||
{
|
|
||||||
"name": "default-roles-forte",
|
|
||||||
"composites": {
|
|
||||||
"client": {
|
|
||||||
"broker": ["read-token"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
82
infra/values/upc-dev/vaultwarden-values.yaml
Normal file
82
infra/values/upc-dev/vaultwarden-values.yaml
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
adminToken:
|
||||||
|
existingSecret: "prod-db-creds"
|
||||||
|
existingSecretKey: "adminToken"
|
||||||
|
domain: "https://vaultwarden.forteapps.net"
|
||||||
|
signupsAllowed: false
|
||||||
|
resourceType: StatefulSet
|
||||||
|
database:
|
||||||
|
type: postgresql
|
||||||
|
host: vaultwarden-postgresql
|
||||||
|
port: "5432"
|
||||||
|
dbName: vaultwarden
|
||||||
|
existingSecret: prod-db-creds
|
||||||
|
existingSecretKey: DATABASE_URL
|
||||||
|
existingSecretUserKey: pgusername
|
||||||
|
existingSecretPasswordKey: pgpassword
|
||||||
|
ingress:
|
||||||
|
enabled: true
|
||||||
|
class: "traefik"
|
||||||
|
tls: true
|
||||||
|
tlsSecret: vaultwarden-tls
|
||||||
|
hostname: vaultwarden.forteapps.net
|
||||||
|
additionalAnnotations:
|
||||||
|
cert-manager.io/cluster-issuer: letsencrypt-prod
|
||||||
|
gethomepage.dev/enabled: "true"
|
||||||
|
gethomepage.dev/name: "VaultWarden"
|
||||||
|
gethomepage.dev/description: "Password management"
|
||||||
|
gethomepage.dev/group: "Security"
|
||||||
|
gethomepage.dev/icon: "vaultwarden"
|
||||||
|
gethomepage.dev/href: "https://vaultwarden.forteapps.net"
|
||||||
|
|
||||||
|
replicas: 1
|
||||||
|
# Multi-Attach error for volume "pvc-102ec9a4-dccd-4cba-bb4b-650f7d934c81" Volume is already used by pod(s) vaultwarden-7f568875c7-m9cgs
|
||||||
|
|
||||||
|
service:
|
||||||
|
sessionAffinity: ClientIP
|
||||||
|
sessionAffinityConfig:
|
||||||
|
clientIP:
|
||||||
|
timeoutSeconds: 10800
|
||||||
|
|
||||||
|
smtp:
|
||||||
|
host: smtp.office365.com
|
||||||
|
security: starttls
|
||||||
|
port: 587
|
||||||
|
authMechanism: "Login"
|
||||||
|
from: noreply@fortedigital.com
|
||||||
|
fromName: "Forte Bitwarden Administrator"
|
||||||
|
debug: true
|
||||||
|
existingSecret: prod-db-creds
|
||||||
|
username:
|
||||||
|
existingSecretKey: SMTP_USERNAME
|
||||||
|
password:
|
||||||
|
existingSecretKey: SMTP_PASSWORD
|
||||||
|
|
||||||
|
storage:
|
||||||
|
data:
|
||||||
|
name: "vaultwarden-data"
|
||||||
|
size: "5Gi"
|
||||||
|
class: ""
|
||||||
|
path: "/data"
|
||||||
|
keepPvc: true
|
||||||
|
accessMode: "ReadWriteOnce"
|
||||||
|
|
||||||
|
attachments:
|
||||||
|
name: "vaultwarden-files"
|
||||||
|
size: "5Gi"
|
||||||
|
class: ""
|
||||||
|
path: /files
|
||||||
|
keepPvc: true
|
||||||
|
accessMode: "ReadWriteOnce"
|
||||||
|
|
||||||
|
sso:
|
||||||
|
enabled: true
|
||||||
|
existingSecret: vaultwarden-oidc-credentials
|
||||||
|
authority: "https://id.forteapps.net/realms/forte"
|
||||||
|
scopes: "email profile"
|
||||||
|
onlySSO: true
|
||||||
|
pkce: true
|
||||||
|
signupsMatchEmail: true
|
||||||
|
clientId:
|
||||||
|
existingSecretKey: client-id
|
||||||
|
clientSecret:
|
||||||
|
existingSecretKey: client-secret
|
||||||
Reference in New Issue
Block a user