24 Commits

Author SHA1 Message Date
66de9b8a0a replicas 2026-05-16 15:48:13 +02:00
716c552be9 ns 2026-05-16 15:44:04 +02:00
f048b47a0f vaultwarden 2026-05-16 15:39:55 +02:00
66f40427ee mappings 2026-05-15 15:47:25 +02:00
332881cbd0 fix 2026-05-14 23:47:14 +02:00
f363afa087 browser flow override 2026-05-14 23:43:40 +02:00
bc42347cb6 gitea+ACCOUNT_LINKING 2026-05-14 21:30:53 +02:00
80d7bff4bc groups 2026-05-14 21:18:17 +02:00
3644a3ec87 mappers 2026-05-14 21:14:57 +02:00
bd478478f1 fix attemt 2026-05-14 20:40:44 +02:00
67b1d95509 account linking 2026-05-14 19:39:38 +02:00
fff95d98a5 remove protocol mappers 2026-05-13 23:15:28 +02:00
8b743efa43 KC fix 2026-05-13 23:13:09 +02:00
4ca9039686 kpolicy 2026-04-29 12:54:07 +02:00
6a9eadbde8 vault ignore diffs 2026-04-29 12:50:10 +02:00
f19f7c9237 icon 2026-04-29 12:07:04 +02:00
5a459d486e dbunk-demo 2026-04-29 10:53:35 +02:00
31fb476a78 row 2026-04-29 10:06:02 +02:00
a088425b70 homepage config 2026-04-29 10:04:20 +02:00
b3b3edf82c no header 2026-04-28 23:03:15 +02:00
308755a4b3 layout 2026-04-28 23:02:13 +02:00
db6afaf180 vault
Co-authored-by: Copilot <copilot@github.com>
2026-04-28 22:44:57 +02:00
5a2f9a1b88 Update infra/values/base/keycloak-values.yaml
Signed-off-by: Danijel Simeunovic <danijel.simeunovic@fortedigital.com>
2026-04-28 19:27:38 +00:00
1c6f18b67c homepage 2026-04-28 20:38:59 +02:00
32 changed files with 701 additions and 4 deletions

View File

@@ -57,7 +57,7 @@ This repository contains the complete GitOps configuration for our Kubernetes cl
### What's Inside ### What's Inside
- **Infrastructure Applications**: Traefik, Cert-Manager, Kyverno, Prometheus, Grafana, Loki, Tempo, Sealed Secrets - **Infrastructure Applications**: Traefik, Cert-Manager, Kyverno, Prometheus, Grafana, Loki, Tempo, Sealed Secrets, Homepage (platform dashboard)
- **Business Applications**: MCP10X, MusicMan, Dot-AI Stack, ArgoCD MCP - **Business Applications**: MCP10X, MusicMan, Dot-AI Stack, ArgoCD MCP
- **Policies**: Kyverno security policies for secret management, namespace controls, pod verification - **Policies**: Kyverno security policies for secret management, namespace controls, pod verification
- **Monitoring**: Full observability stack with metrics, logs, traces, and alerting - **Monitoring**: Full observability stack with metrics, logs, traces, and alerting

View File

@@ -0,0 +1,47 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: dbunk-demo
namespace: argocd
annotations:
argocd.argoproj.io/sync-wave: "12"
labels:
app.kubernetes.io/name: dbunk-demo
app.kubernetes.io/part-of: apps
app.kubernetes.io/managed-by: argocd
finalizers:
- resources-finalizer.argocd.argoproj.io
spec:
project: default
sources:
- repoURL: ssh://git@git.forteapps.net:2222/Forte/forte-helm.git
path: forteapp
targetRevision: HEAD
helm:
valueFiles:
- $values/dbunk-demo/values.yaml
- repoURL: ssh://git@git.forteapps.net:2222/Forte/helm-prod-values.git
targetRevision: HEAD
ref: values
destination:
server: https://kubernetes.default.svc
namespace: dbunk-demo
syncPolicy:
automated:
prune: true
selfHeal: true
allowEmpty: false
syncOptions:
- CreateNamespace=true
- Validate=true
- ServerSideApply=true
retry:
limit: 5
backoff:
duration: 5s
factor: 2
maxDuration: 3m

View File

@@ -0,0 +1,4 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- dbunk-demo.yaml

View File

@@ -2,6 +2,7 @@ apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization kind: Kustomization
resources: resources:
- ../../base - ../../base
- dbunk-demo
# 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

View File

@@ -28,7 +28,6 @@ Bootstrap()
Gitea() Gitea()
{ {
echo "Installing secret..." echo "Installing secret..."
kubectl apply -f "secrets/"
kubectl apply -f "private/${CLUSTER}/gitea-repo-main.yaml" kubectl apply -f "private/${CLUSTER}/gitea-repo-main.yaml"
kubectl apply -f "private/${CLUSTER}/main.key" kubectl apply -f "private/${CLUSTER}/main.key"
} }

View File

@@ -725,6 +725,59 @@ TLS terminates at Traefik; ArgoCD runs in insecure mode behind the proxy.
## Infrastructure Components ## Infrastructure Components
### Homepage (Platform Dashboard)
**Chart**: `jameswynn/homepage`
**Namespace**: `homepage`
**URL**: `https://start.forteapps.net`
Platform dashboard that auto-discovers deployed apps via Kubernetes service annotations.
**Discovery mechanism**: Services annotated with `gethomepage.dev/enabled: "true"` appear in the dashboard. Apps not deployed = annotations absent = not shown. Fully dynamic per environment.
**Annotated services**:
| Service | Namespace | Group | Widget |
|---------|-----------|-------|--------|
| `gitea-http` | `gitea` | DevOps | `gitea` |
| `argocd-server` | `argocd` | DevOps | `argocd` |
| `keycloak` | `keycloak` | Identity | none |
| `grafana` | `monitoring` | Monitoring | `grafana` |
| `karpor-server` | `karpor` | DevOps | none |
**Adding a new app**: Annotate the app's Service in its Helm values:
```yaml
service:
annotations:
gethomepage.dev/enabled: "true"
gethomepage.dev/name: "My App"
gethomepage.dev/description: "What it does"
gethomepage.dev/group: "GroupName"
gethomepage.dev/icon: "icon-name" # https://github.com/walkxcode/dashboard-icons
gethomepage.dev/href: "https://myapp.forteapps.net"
# Optional live widget:
gethomepage.dev/widget.type: "myapp"
gethomepage.dev/widget.url: "https://myapp.forteapps.net"
# gethomepage.dev/widget.key: "{{HOMEPAGE_VAR_MYAPP_TOKEN}}"
```
**Widget API credentials**: Inject via env vars into the Homepage pod:
```yaml
# In homepage-values.yaml per environment
env:
- name: HOMEPAGE_VAR_GRAFANA_TOKEN
valueFrom:
secretKeyRef:
name: homepage-widget-credentials
key: grafana-token
```
Then reference as `gethomepage.dev/widget.key: "{{HOMEPAGE_VAR_GRAFANA_TOKEN}}"`.
**Values files**:
- `infra/values/base/homepage-values.yaml` — RBAC, kubernetes mode, layout
- `infra/values/{env}/homepage-values.yaml` — hostname per environment
---
### Traefik ### Traefik
**Chart**: `traefik/traefik` **Chart**: `traefik/traefik`
@@ -1088,6 +1141,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`)

View File

@@ -0,0 +1,21 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: homepage-services-reader
rules:
- apiGroups: [""]
resources: ["services"]
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: homepage-services-reader
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: homepage-services-reader
subjects:
- kind: ServiceAccount
name: homepage
namespace: homepage

View File

@@ -0,0 +1,16 @@
---
apiVersion: bitnami.com/v1alpha1
kind: SealedSecret
metadata:
creationTimestamp: null
name: homepage-widget-credentials
namespace: homepage
spec:
encryptedData:
HOMEPAGE_VAR_GITEA_TOKEN: AgAVN1C931EQpn+sodr3CpjlhORfJVTW8aUr+pGZQb+65Pb8QLGeVGVa7Jv60gDJUX3r+93/jMrEbCOeDL6I4qCz/V35wMCxFZLnXIdkmto0W4MKt6cK8To1/OP7EhQJOGBlSuOFsrwoy+HDtvLIqmyF0nrxhTusm9/NHrw+gCVwSTPhiAX1MCuSOSRWpbXvyNphW8j7aqUaV6ixDt424Fe4alEIShYELcS3EX/VPgsf2p2bhvBRCQOh3LEprkuxSFMuPfCBk06TPTbIN4saNVm0Ke0zW/pxkVNSiIxEnKjOmpPJtacsfWN7du+nQbx276G2qvWrf+iawJVq0Z/SLikA/NUFBL6EjSRfgE3cSOri8sbxsd0AycsFGyp98EM29wE+WOQl52M/lwl02EmCivqkICSO7Jp9pM1ScbmRMa5vcnupsGbVDxhRKLqxhAskt/BXDkRzvHN31gH3YmelES3JuqNMHV0urFxmX2oOX9Pxbtv63csc+zhy1Ui5aoex7TPnLdk7kYLSAE2MSrzT6wHvVhBC5kNnDYVrLehvJrT+eNh0MOLx2wkuJmIOxRAGUyNi5DfDnP6qnvj2aefEymLuOXAIUXH8DbeBtrjsd74HX2hhIfBlPkXvhJR3ks7i5RXjK2/YYHkgJ+nJoW80S9N7ciaRy103g74TNJZt6QzzL5Vb80qZ6yQOD4G081KmTLDmhHjJVIIv9M3nLh2s0IeBV3/Z5qHZmtjN7sSaKAn4MIr5FaH9quhx
HOMEPAGE_VAR_GRAFANA_TOKEN: AgBloBlOlP+R/4VizE1CGpj0wyiwU14BemAnuUpld7OvOGc67dwfDPyponkQXjAZg3UU2cZ70A51WUAuVlAr+25Ktlf/FW2OBqj+1BJOCqMMyu+kv026yjX2aB8dKGzlTxgF8aji+j1mC8vP3vvmgI4Zf2HQAH7uFwLfeo8+QnV5EyhcExSS0xDne+VtOP9jNXbPRayry0DdyRVtaeKAiZacO+45oAJWszWOwmoMTg9FZQkLjER6Q0tyI6NnoNObsFCnh56chZTdzBOYtmPnwld1bP2FjoJDqn8AfRwbPTIj7t0eFP7WLUO7GQKpxVl+pFwJLb5xCOw2+HNtp1BhNCu7icuc0P88IlvwzkbN0lXJbYigVOzyjEo8f/al1DXPM4WaB/Nqmr7Mtt8KTRh2WMVTgiX5jsu25D0rGDvY9gqfBBqswkRhCLsG0v0EN32zXj1/52KYdmB7pk/+2lMwSaGMS11MOenHeU1Z95fGxm9f3EGF0E8xlFr4FowgsNwr+tJQqpM0bT/4mZnaQbGWtKPFizMtsfQFm+rHFcNCrGaOuecslmiIJs8lTm18KlrncsGfxNS64tVXk+LvydU0rwybvpg2rQjEWtAl1IQsaaiz96OAlYxxK1MGxN7KE6F8R4kfnWTZ5Fs1KMmd/DOIVBXyCbqXxk8pbekmaIeNSfv92JNZ0QNJWsBa2vgQ24WI2pb4XiR0BvtLpt3BVlZUcSK92SzUblWmYWVMwHYCJkEeEUV1PhYEmyiN+V/Kq5Qb
template:
metadata:
creationTimestamp: null
name: homepage-widget-credentials
namespace: homepage

View File

@@ -0,0 +1,43 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: homepage
namespace: argocd
annotations:
argocd.argoproj.io/sync-wave: "3"
labels:
app.kubernetes.io/name: homepage
app.kubernetes.io/part-of: platform
app.kubernetes.io/managed-by: argocd
finalizers:
- resources-finalizer.argocd.argoproj.io
spec:
project: default
sources:
- repoURL: https://jameswynn.github.io/helm-charts
chart: homepage
targetRevision: "2.1.0"
helm:
releaseName: homepage
valueFiles:
- $values/infra/values/base/homepage-values.yaml
- $values/infra/values/upc-dev/homepage-values.yaml
- repoURL: ssh://git@git.forteapps.net:2222/Forte/launchpad.git
targetRevision: HEAD
ref: values
destination:
server: https://kubernetes.default.svc
namespace: homepage
syncPolicy:
automated:
prune: true
selfHeal: true
allowEmpty: false
syncOptions:
- CreateNamespace=true
- Validate=true
- ServerSideApply=true

View File

@@ -0,0 +1,6 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- homepage.yaml
- homepage-widget-credentials-sealed.yaml
- homepage-extra-rbac.yaml

View File

@@ -21,3 +21,5 @@ resources:
- grafana-dashboards - grafana-dashboards
- karpor - karpor
- databunker - databunker
- homepage
- vault

View File

@@ -27,7 +27,6 @@ spec:
automated: automated:
prune: true prune: true
selfHeal: true selfHeal: true
allowEmpty: false
syncOptions: syncOptions:
- CreateNamespace=true - CreateNamespace=true
- Validate=true - Validate=true

View File

@@ -0,0 +1,4 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- vault.yaml

View File

@@ -0,0 +1,49 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: vault
namespace: argocd
annotations:
argocd.argoproj.io/sync-wave: "1"
labels:
app.kubernetes.io/name: vault
app.kubernetes.io/part-of: security
app.kubernetes.io/managed-by: argocd
finalizers:
- resources-finalizer.argocd.argoproj.io
spec:
project: default
sources:
- repoURL: https://helm.releases.hashicorp.com
chart: vault
targetRevision: "0.32.0"
helm:
releaseName: vault
valueFiles:
- $values/infra/values/base/vault-values.yaml
- $values/infra/values/upc-dev/vault-values.yaml
- repoURL: ssh://git@git.forteapps.net:2222/Forte/launchpad.git
targetRevision: HEAD
ref: values
destination:
server: https://kubernetes.default.svc
namespace: vault
syncPolicy:
automated:
prune: true
selfHeal: true
allowEmpty: false
syncOptions:
- CreateNamespace=true
- Validate=true
- ServerSideApply=true
ignoreDifferences:
- group: apps
kind: StatefulSet
jsonPointers:
- /spec/volumeClaimTemplates

View File

@@ -13,9 +13,19 @@ resources:
- ../../base/prometheus - ../../base/prometheus
- ../../base/sealedsecrets - ../../base/sealedsecrets
- ../../base/tempo - ../../base/tempo
- ../../base/homepage
- ../../base/traefik-application - ../../base/traefik-application
patches: patches:
# Homepage: swap upc-dev → aks-dev
- target:
kind: Application
name: homepage
patch: |
- op: replace
path: /spec/sources/0/helm/valueFiles/1
value: $values/infra/values/aks-dev/homepage-values.yaml
# Traefik: swap upc-dev → aks-dev # Traefik: swap upc-dev → aks-dev
- target: - target:
kind: Application kind: Application

View File

@@ -2,6 +2,7 @@ apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization kind: Kustomization
resources: resources:
- ../../base - ../../base
- 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

View File

@@ -0,0 +1,5 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- vaultwarden.yaml
- vaultwarden-db-secret-sealed.yaml

View File

@@ -0,0 +1,18 @@
---
apiVersion: bitnami.com/v1alpha1
kind: SealedSecret
metadata:
creationTimestamp: null
name: prod-db-creds
namespace: vaultwarden
spec:
encryptedData:
SMTP_PASSWORD: AgARC3vcVD2SC8GUry5SYylyiS39eKQUFAjqT4dpXQsoJX7QSLfd7Ta68BURg8Q5e2zWdzIl+nrUyBy/4TMXeHjSUhcfsH0RY2logMuTn96kV/V7YKm1Zw394hrJ3uroB7iFkf/TwiXuwFS1QvppxlpXNWVClHs+r0aW3vD2s7ViFxFqcPYGfNKlGvW2aLU6XER/TUXCffoSmHgl0wut5UaZEo+321AAaqcmk90Te/Pv4oU0SfFGn/+14zDR3VT4s6u8rgYQcSB23p2f3X3+8tCLgSLclyzSXAVfclMBYCuCtOzFjgXOQLoYfW3WW48KqsFKsoZsI/dop8L/y2P78xGJ5gYNiVcH6vEMfOr6wOTISyXqQIi3a/KZcNSY4ZZ7kH13aqru3Fpb4XAGjcmEEfWfOQ9IcPBj6Yh9pNOhxlQHPqXR9zrwx//iXdH2bsbEJ2vNHQhU9uc4t3dO1VnLO/icvMr3CFEuaB4mFDThVrPGOEi5s1YKPTHb1j8B92WSy6aNmNro0977cbbJs/linNox3rNa20kzQPfU2pdlC31vIcpMCM7vtUnx16QHyjUNe/whFqIbSG3mE19jbjIvGo0d7jhBWZYQin+m1MRv/Tv8VjzYe6FciIFX33pNTWkwkvFq+s8eQcyruWCe5hLlF361FklqXcSh1tMyqcfOScNRPxUPlWumkGPDmonULJPkmAs7eJmxKlvinrAPs8eiP7c/1SPW6FdMmxT7sq/27TII
SMTP_USERNAME: AgC1Zsv5l5Wbrq7VZC2U55+0/LQvZEbsmlxq2O5Z+Xp/admdqptEBGlLKEdIn7CmyBzvmrmWasmN4NJPJHoeLWn7SgsoULTu1UQ3W9kgcrXUJ52dwOrYLMJUxJuh+OD9HEJejfOMksc2rSM69I4NUc+NXaDSZOo+gzldWzBN7nCa778NcnMgJxVcT4gqjTIRB9EOrCo4f3ldFJzVJW7qNnxurN0UZQ51y+nj+4z2R+LvfOJ1BT5YQC+nmx80HVBMdQWK5WO4QdxCtenXfiFDNcGK3MK/Exd+kubOWse85CMt2dR0GWuIfIOp+t4XQXfb1pxhTibh/fGae9dD0RpSX1c8hobkpXaDJIYeb7ZQF5J6Zf68fgCn0YircY1hB4yF7uX5CQL1yv76M4tM9yuOn5FTJaIG6byWn/RsHZ7KPIUSd1mOce9ZqfTkKzvC/wfX45UMhPEsdXF9o67mAtOpdmBGrmeDD+7GwPwKXz3JgDovlGtzvLvMZ27+x1dpC8LrcAjcKXXGKczbs3L2Pc+tymd9dis36RvlFLEgQG32ffQu5vQXqGcoSEnlZ0l39qoU9EItkA5kp0isGiJI46hJtAdTTNr0roymvrfDyLXpAvXTQYaVMC7/8KVb2r3kIPKtnsDuU2A57ceiqtdWQgUarPn4F0O3SaCnprmTm2thgCgQOkW7BGlN3CCsVboZUIOlFr7CwTswB9ZI6tzOj2WsUOhriTfIuXv3kyrFCspo
pgpassword: AgB7F1Nvm2sjBOneDFux2mc/qni32jaq+KccTWkS7UZWWgA37owrE/XvDSOXZ0ZkrpBfhvCnsrh7/mbVnZYNWCd/GgxI2txnkp9MxW5JLpJiaZZmzznI229BgG9I08vg6ciuUS+bvRw9XJFD7SAmgeA3NaDKAHRNIhu3CFEKQJANity+pKHY1zK6gX6ubmllFtjEJg2pijM3EeSNuXdAFXZlsYIJMqFzlvQrb4MV7qeqsvW2qMeJBElMnas60l3JgeUYtsIwh6720m6FFKGXYQLm4cKbByC0M1C0/Nfwnd9j+xgIgyXharQFmgyp1qQBM+MAHxnHoHCE3V9cJqy1nCy33M16YYsZGOuAkHB9ks9I7NxGAKKjAIm5DccW7zbYINzTQKAUYIF/VhVosHv0thAHjfuH7fGzSmo9BHrLTQE3tO5RF40X2GgKFxP/R5lA+dCtR2QBNot0DaL2TEJoPc0czSYPY5y92FDOQ1j9jvcet18tkJN+bzCKwiG+BxtD0eH+tv1EAZTwvyl43xlU3E3RwWgSmOWcusMrn92fhsHwNFs9mMeeM8qeAVq4xUkatbKoijHm6q03tMgp2T6iT3EoVNLzWz+754mLQxt6serkBS8U7Mkxwpfitf64ANLaQyMF8t9Rao0c8Q/ZkIl9TEczbCPX3DvlnsoSPKDMWGB9gTzKbvvH0+Gcxxs+LZFigE7SQ20kYMlQpD8uo15ufWpMSGmFJxvto55fYgA0+wJmqe18ERy1QjxCqQYG7A==
pgusername: AgAvYmIjfz5UbstZli9gpc77rc+oAft7NYIHFrSClyV0Ugt6UU+icMMlLbU92roy7J9XUHuWoXoK5vh0y/XeF95ce1VJC0/zvMK2OXmpfERbyNvyCpwzCFtzYJ4LO7yOi8PAPstzuziqnvLt+GLCwk1enU+IWHI7G2A/qIeWEww5+Y5a4WevVrchp0Wh87PdJ88IT5EiF7qBT2ipbcSoB+Gon962nbw8+pnFedmRcUQcdOf0tQBBZOl5TUVJ6mn4WIY8u6/yOwACMlUXQ553rxXYwGKyTRjI0KbTWwpgeCJiqokyrw/RcShD6qJvZGePdq6rNmmkELOHCPo9z/WvXQIDHbuPldvcglyHuN2w4tsBcGukbmjitwS6wxYD0vp3er3FI9+0tRnD9zlkLiUpcaLi9Rrm7NPS/JP1dbGcHz7fJNXgbMZRGRx3DjV73Qnz6YHvOHT4g6BI2+9JytriRKSOJk/FlDCINgrO+6zMrbxKzBTW3+FK1cc41sJ9zClbV603wsMgtkmB1sZL4xcLmq5wOuk19uO9TsK0Xnf+ajuFUkQm42DVxtTZ9HObLnP8eygn1WiMDv3ks6W7HIpJTpc2YJVU/Pg/kTeQgBKS0JRTkzpJFPHV2UrkLTr0U6ToPYOb2SWBnPI+Lp3cTOeUsbKOylBzx4uUJGoZUL5pAorjd5tDHJhMyMm589m5J3mGMXuhXO1cWg80
template:
metadata:
creationTimestamp: null
name: prod-db-creds
namespace: vaultwarden

View File

@@ -0,0 +1,49 @@
apiVersion: v1
kind: Namespace
metadata:
name: vaultwarden
---
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

View File

@@ -0,0 +1,15 @@
ingress:
main:
enabled: true
ingressClassName: traefik
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
hosts:
- host: start.forteapps.net
paths:
- path: /
pathType: Prefix
tls:
- secretName: homepage-tls
hosts:
- start.forteapps.net

View File

@@ -35,6 +35,12 @@ server:
ingressClassName: traefik ingressClassName: traefik
annotations: annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod cert-manager.io/cluster-issuer: letsencrypt-prod
gethomepage.dev/enabled: "true"
gethomepage.dev/name: "ArgoCD"
gethomepage.dev/description: "GitOps continuous delivery"
gethomepage.dev/group: "DevOps"
gethomepage.dev/icon: "argo-cd"
gethomepage.dev/href: "https://argocd.forteapps.net"
tls: true tls: true
extraArgs: extraArgs:
- --insecure - --insecure

View File

@@ -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:
@@ -114,6 +115,15 @@ ingress:
className: traefik className: traefik
annotations: annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod cert-manager.io/cluster-issuer: letsencrypt-prod
gethomepage.dev/enabled: "true"
gethomepage.dev/name: "Gitea"
gethomepage.dev/description: "Git hosting & CI/CD"
gethomepage.dev/group: "DevOps"
gethomepage.dev/icon: "gitea"
gethomepage.dev/href: "https://git.forteapps.net"
gethomepage.dev/widget.type: "gitea"
gethomepage.dev/widget.url: "https://git.forteapps.net"
gethomepage.dev/widget.key: "{{HOMEPAGE_VAR_GITEA_TOKEN}}"
hosts: hosts:
- host: git.forteapps.net - host: git.forteapps.net
paths: paths:

View File

@@ -3,11 +3,21 @@ ingress:
ingressClassName: traefik ingressClassName: traefik
annotations: annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod cert-manager.io/cluster-issuer: letsencrypt-prod
gethomepage.dev/enabled: "true"
gethomepage.dev/name: "Grafana"
gethomepage.dev/description: "Metrics & observability dashboards"
gethomepage.dev/group: "Monitoring"
gethomepage.dev/icon: "grafana"
gethomepage.dev/href: "https://grafana.forteapps.net"
tls: tls:
- secretName: grafana-tls - secretName: grafana-tls
hosts: hosts:
- grafana.forteapps.net - grafana.forteapps.net
persistence:
enabled: true
size: 1Gi
resources: resources:
requests: requests:
cpu: 50m cpu: 50m

View File

@@ -0,0 +1,72 @@
# Homepage Helm Values
# Chart: jameswynn/homepage — https://gethomepage.dev
# Discovery: K8s service annotations (gethomepage.dev/*)
# Each deployed app annotates its own Service — apps not deployed = not visible.
# RBAC ClusterRole — required for cluster-wide service annotation scanning
enableRbac: true
serviceAccount:
create: true
name: homepage
config:
# Scan all namespaces for services with gethomepage.dev/enabled: "true"
kubernetes:
mode: cluster
traefik: true
settings:
title: "Platform"
headerStyle: clean
layout:
Apps:
style: row
columns: 3
Security:
style: row
columns: 3
Tools:
style: row
header: false
columns: 2
DevOps:
style: column
rows: 2
Monitoring:
style: column
rows: 1
# Top-of-page cluster overview widget
widgets:
- kubernetes:
cluster:
show: true
cpu: true
memory: true
showLabel: true
label: "Cluster"
nodes:
show: true
cpu: true
memory: true
showLabel: true
# In-cluster entries come from K8s service annotations.
# External (out-of-cluster) services are listed here statically.
bookmarks: []
services: []
resources:
requests:
cpu: 10m
memory: 128Mi
limits:
cpu: 100m
memory: 256Mi
env:
- name: HOMEPAGE_ALLOWED_HOSTS
value: start.forteapps.net
envFrom:
- secretRef:
name: homepage-widget-credentials

View File

@@ -18,6 +18,12 @@ ingress:
ingressClassName: traefik ingressClassName: traefik
annotations: annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod cert-manager.io/cluster-issuer: letsencrypt-prod
gethomepage.dev/enabled: "true"
gethomepage.dev/name: "Keycloak"
gethomepage.dev/description: "Identity & access management"
gethomepage.dev/group: "Security"
gethomepage.dev/icon: "keycloak"
gethomepage.dev/href: "https://id.forteapps.net/admin/forte-test/console/"
metrics: metrics:
enabled: true enabled: true
@@ -52,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: |
{ {
@@ -95,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"
}
} }
] ]
}, },
@@ -167,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"

View File

@@ -0,0 +1,36 @@
# HashiCorp Vault Helm Chart Values
# Chart: hashicorp/vault v0.32.0
server:
standalone:
enabled: true
dataStorage:
enabled: true
size: 5Gi
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 250m
memory: 256Mi
ingress:
enabled: true
ingressClassName: traefik
pathType: Prefix
activeService: true
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
gethomepage.dev/enabled: "true"
gethomepage.dev/name: "Vault"
gethomepage.dev/description: "Secrets management"
gethomepage.dev/group: "Security"
gethomepage.dev/icon: "vault"
gethomepage.dev/href: "https://vault.forteapps.net"
ui:
enabled: true
serviceType: ClusterIP

View File

@@ -0,0 +1,3 @@
image:
tag: "1.36.0-alpine"
domain: "https://vaultwarden.forteapps.net"

View File

@@ -1,3 +1,10 @@
ingress: ingress:
enabled: true enabled: true
host: databunker.forteapps.net host: databunker.forteapps.net
annotations:
gethomepage.dev/enabled: "true"
gethomepage.dev/name: "Databunker"
gethomepage.dev/description: "Secure Database for PII and PCI Records"
gethomepage.dev/group: "Security"
gethomepage.dev/icon: "double-take"
gethomepage.dev/href: "https://databunker.forteapps.net"

View File

@@ -0,0 +1,65 @@
ingress:
main:
enabled: true
ingressClassName: traefik
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
hosts:
- host: start.forteapps.net
paths:
- path: /
pathType: Prefix
tls:
- secretName: homepage-tls
hosts:
- start.forteapps.net
config:
settings:
title: "Forte Platform"
headerStyle: clean
layout:
Apps:
style: row
columns: 2
Security:
style: row
columns: 3
Tools:
style: row
header: false
columns: 2
DevOps:
style: column
rows: 2
Monitoring:
style: column
rows: 1
# Top-of-page cluster overview widget
widgets:
- kubernetes:
cluster:
show: true
cpu: true
memory: true
showLabel: true
label: "Cluster"
nodes:
show: true
cpu: true
memory: true
showLabel: true
# In-cluster entries come from K8s service annotations.
# External (out-of-cluster) services are listed here statically.
bookmarks: []
services:
- Apps:
- Forte Benken:
href: https://benken.hackathon.forteapps.net
description: Teknisk kompetanse fra offentlige anbud
icon: forte
- Forte Feedback:
href: https://feedback.forteapps.net
description: Fortes internal feedback app
icon: forte

View File

@@ -0,0 +1,9 @@
server:
ingress:
hosts:
- host: vault.forteapps.net
paths: []
tls:
- secretName: vault-tls
hosts:
- vault.forteapps.net

View File

@@ -0,0 +1,45 @@
database:
type: postgresql
existingSecret: prod-db-creds
existingSecretUserKey: pgusername
existingSecretPasswordKey: pgpassword
ingress:
enabled: true
class: "traefik"
tlsSecret: vw-forteapps-net-crt
hostname: bitwarden.forteapps.net
replicas: 1
service:
sessionAffinity: ClientIP
sessionAffinityConfig:
clientIP:
timeoutSeconds: 10800
smtp:
host: smtp.office365.com
from: no-reply@forteapps.net
fromName: "Forte Bitwarden Administrator"
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"