Skip to content
Open
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
8 changes: 4 additions & 4 deletions charts/keycloak/templates/keycloak-users-external-secret.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,18 @@ spec:
data:
- secretKey: qtodo_admin_password
remoteRef:
key: secret/data/global/keycloak-users
key: {{ .Values.keycloak.users.passwordVaultKey }}
property: qtodo-admin-password
- secretKey: qtodo_user1_password
remoteRef:
key: secret/data/global/keycloak-users
key: {{ .Values.keycloak.users.passwordVaultKey }}
property: qtodo-user1-password
- secretKey: rhtas_user_password
remoteRef:
key: secret/data/global/keycloak-users
key: {{ .Values.keycloak.users.passwordVaultKey }}
property: rhtas-user-password
- secretKey: rhtpa_user_password
remoteRef:
key: secret/data/global/keycloak-users
key: {{ .Values.keycloak.users.passwordVaultKey }}
property: rhtpa-user-password
{{- end }}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,6 @@ spec:
data:
- secretKey: client_secret
remoteRef:
key: secret/data/global/oidc-client-secret
key: {{ .Values.keycloak.oidcSecrets.qtodo.vaultPath }}
property: client-secret
{{- end }}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ spec:
data:
- secretKey: client_secret
remoteRef:
key: secret/data/global/rhtpa-oidc-cli-secret
key: {{ .Values.keycloak.oidcSecrets.rhtpaCli.vaultPath }}
property: client-secret
{{- end }}

17 changes: 14 additions & 3 deletions charts/keycloak/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ keycloak:
adminUser:
enabled: true
username: admin
passwordVaultKey: secret/data/global/keycloak
# Keycloak admin password (infra)
passwordVaultKey: secret/data/hub/infra/keycloak/keycloak
secretName: keycloak-admin-user
defaultConfig: true
defaultRealm:
Expand Down Expand Up @@ -349,13 +350,23 @@ keycloak:
name: keycloak
postgresqlDb:
database: keycloak
passwordVaultKey: secret/data/global/keycloak
# Keycloak DB password path (infra)
passwordVaultKey: secret/data/hub/infra/keycloak/keycloak
secretName: postgresql-db
username: keycloak
realms: []
tls:
secret: keycloak-tls
serviceServing: true
users:
passwordVaultKey: secret/data/global/keycloak-users
# User credentials path (infra)
passwordVaultKey: secret/data/hub/infra/users/keycloak-users
secretName: keycloak-users
# OIDC client secrets for realm configuration
oidcSecrets:
# QTodo OIDC client secret (app-level)
qtodo:
vaultPath: secret/data/apps/qtodo/qtodo-oidc-client
# RHTPA CLI OIDC client secret (infra)
rhtpaCli:
vaultPath: secret/data/hub/infra/rhtpa/rhtpa-oidc-cli
25 changes: 16 additions & 9 deletions charts/qtodo/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,9 @@ app:
secretName: qtodo-registry-auth
user: quay-user
# domain: quay-registry-quay-quay-enterprise.apps.example.com
vaultPath: secret/data/global/quay-users
passwordVaultKey: password
# Registry credentials - stored in quay path
vaultPath: secret/data/hub/infra/quay/quay-users
passwordVaultKey: quay-user-password
spiffeHelper:
name: registry.redhat.io/zero-trust-workload-identity-manager/spiffe-helper-rhel9
version: v0.10.0
Expand Down Expand Up @@ -53,21 +54,26 @@ app:
- qtodo

# Vault configuration for SPIFFE integration
# Uses SPIFFE JWT to authenticate and fetch DB password
vault:
url: ""
role: "qtodo-role"
secretPath: "secret/data/global/keycloak-users"
role: "qtodo"
# QTodo secrets path (app-level isolation)
secretPath: "secret/data/apps/qtodo/qtodo-db"

# OIDC External Secret configuration
oidcSecret:
enabled: true
name: "oidc-client-secret"
vaultPath: "secret/data/global/oidc-client-secret"

# Truststore configuration for Java CA certificates
# QTodo OIDC secret path (app-level isolation)
vaultPath: "secret/data/apps/qtodo/qtodo-oidc-client"

# Truststore configuration for Java CA certificates (PKCS12 format)
truststore:
enabled: true
vaultPath: "secret/data/global/qtodo-truststore"
secretName: "qtodo-truststore-secret"
# QTodo truststore password path (app-level isolation)
vaultPath: "secret/data/apps/qtodo/qtodo-truststore"

# PostgreSQL database configuration
postgresql:
Expand All @@ -78,4 +84,5 @@ postgresql:
secretName: qtodo-db-secret
database: tasks
username: qtodo_user
passwordVaultKey: secret/data/global/qtodo
# QTodo DB password path (app-level isolation)
passwordVaultKey: secret/data/apps/qtodo/qtodo-db
2 changes: 1 addition & 1 deletion charts/rhtpa-operator/templates/oidc-cli-secret.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ spec:
data:
- secretKey: client-secret
remoteRef:
key: secret/data/global/rhtpa-oidc-cli-secret
key: {{ .Values.rhtpa.zeroTrust.keycloak.clients.cli.secretVaultPath }}
property: client-secret
{{- end }}

14 changes: 10 additions & 4 deletions charts/rhtpa-operator/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,22 +24,27 @@ rhtpa:
enabled: true
url: "https://vault.vault.svc.cluster.local:8200"
role: "rhtpa"
policy: "global-secret"
secretPath: "secret/data/global/rhtpa"
# Application-specific policy (least privilege)
policy: "rhtpa-secrets"
# RHTPA DB password path (infra)
secretPath: "secret/data/hub/infra/rhtpa/rhtpa-db"
keycloak:
enabled: true
url: "" # Constructed dynamically from global.localClusterDomain in templates
realm: "ztvp"
namespace: "keycloak-system" # Namespace where Keycloak is deployed
instanceName: "keycloak" # Name of the Keycloak CR
userPasswordVaultKey: "secret/data/global/keycloak-users" # Vault path for RHTPA user password
# User credentials - stored in infra users path
userPasswordVaultKey: "secret/data/hub/infra/users/keycloak-users"
# OIDC Client Configuration
clients:
frontend:
clientId: "rhtpa-frontend" # Public client for RHTPA UI
cli:
clientId: "rhtpa-cli" # Confidential client for RHTPA CLI/API
secretName: "rhtpa-oidc-cli-secret" # Kubernetes secret containing client secret
# RHTPA OIDC CLI secret path (infra)
secretVaultPath: "secret/data/hub/infra/rhtpa/rhtpa-oidc-cli"

# TLS Configuration
tls:
Expand Down Expand Up @@ -128,7 +133,8 @@ rhtpa:
name: "rhtpa"
username: "rhtpa"
secretName: "rhtpa-db-secret"
passwordVaultKey: "secret/data/global/rhtpa"
# RHTPA DB password path (infra)
passwordVaultKey: "secret/data/hub/infra/rhtpa/rhtpa-db"
storageSize: "10Gi"
image: "registry.redhat.io/rhel8/postgresql-16"

Expand Down
6 changes: 4 additions & 2 deletions charts/supply-chain/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ rhtpa:
oidcRealm: "ztvp"
clientId: "rhtpa-cli"
clientSecretName: "qtodo-rhtpa-cli-password"
clientSecretVaultPath: "secret/data/global/rhtpa-oidc-cli-secret"
# RHTPA OIDC CLI secret path (infra)
clientSecretVaultPath: "secret/data/hub/infra/rhtpa/rhtpa-oidc-cli"
clientSecretVaultKey: "client-secret"

# qtodo repository configuration
Expand Down Expand Up @@ -43,7 +44,8 @@ registry:
tlsVerify: "true"
user: "quay-user"
passwordVaultKey: "quay-user-password"
vaultPath: "secret/data/global/quay-users"
# Infrastructure secrets - stored in quay path
vaultPath: "secret/data/hub/infra/quay/quay-users"

# spire configuration
spire:
Expand Down
17 changes: 15 additions & 2 deletions common/scripts/vault-utils.sh
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,15 @@ fi

EXTRA_PLAYBOOK_OPTS="${EXTRA_PLAYBOOK_OPTS:-}"

EXTRA_VARS_FILE=$(mktemp)
trap "rm -f ${EXTRA_VARS_FILE}" EXIT

if [ "$(yq ".clusterGroup.applications.vault.jwt.enabled // \"false\"" "${MAIN_CLUSTERGROUP_FILE}")" == "true" ]; then
OCP_DOMAIN="$(oc get dns cluster -o jsonpath='{.spec.baseDomain}')"
OIDC_DISCOVERY_URL="$(yq ".clusterGroup.applications.vault.jwt.oidcDiscoveryUrl" "${MAIN_CLUSTERGROUP_FILE}" | sed "s/{{ \$.Values.global.clusterDomain }}/${OCP_DOMAIN}/g")"
JWT_ROLES="$(yq -o json ".clusterGroup.applications.vault.jwt.roles" "${MAIN_CLUSTERGROUP_FILE}" | jq -rc | sed "s/{{ \$.Values.global.clusterDomain }}/${OCP_DOMAIN}/g")"
JWT_ROLES="$(yq -o json ".clusterGroup.applications.vault.jwt.roles" "${MAIN_CLUSTERGROUP_FILE}" | sed "s/{{ \$.Values.global.clusterDomain }}/${OCP_DOMAIN}/g")"
# Extract JWT policies (policies ending in -jwt-secret)
JWT_POLICIES="$(yq -o json ".clusterGroup.applications.vault.policies" "${MAIN_CLUSTERGROUP_FILE}" | jq '[.[] | select(.name | test("-jwt-secret$"))]')"

if [ "${OIDC_DISCOVERY_URL}" == "null" ] || [ "${JWT_ROLES}" == "null" ] || [ "${JWT_ROLES}" == "[]" ]; then
echo "Vault JWT config is disabled because of missing required fields"
Expand All @@ -46,13 +51,21 @@ if [ "$(yq ".clusterGroup.applications.vault.jwt.enabled // \"false\"" "${MAIN_C

else
VAULT_JWT_CONFIG="false"
JWT_ROLES="[]"
JWT_POLICIES="[]"
echo "Vault JWT config is disabled"
fi

# Write extra vars to temp file to handle complex JSON with embedded quotes
cat > "${EXTRA_VARS_FILE}" <<EOF
vault_jwt_roles: ${JWT_ROLES:-[]}
vault_jwt_policies: ${JWT_POLICIES:-[]}
EOF

ansible-playbook -t "${TASK}" \
-e pattern_name="${PATTERN_NAME}" \
-e pattern_dir="${PATTERNPATH}" \
-e vault_jwt_config="${VAULT_JWT_CONFIG}" \
-e oidc_discovery_url="${OIDC_DISCOVERY_URL:-}" \
-e vault_jwt_roles="${JWT_ROLES:-'[]'}" \
-e "@${EXTRA_VARS_FILE}" \
${EXTRA_PLAYBOOK_OPTS} "rhvp.cluster_utils.vault"
2 changes: 1 addition & 1 deletion docs/multi-tier.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ Access the qtodo application in a browser. The URL can be located from the OpenS
1. Select **Networking** -> **Routes** from the lefthand navigation bar
2. Click the arrow next to the the URL underneath the _Location_ column to open the qtodo application in a new browser tab

You will be presented with a login page to access the application. When using the default External Identity Provider (RHBK), two users (`qtodo-admin` and `qtodo-user`) were provisioned automatically. Their initial credentials are stored in a Secret in the `keycloak-system` namespace called `keycloak-users`. You can reveal the credentials by switching to the tab containing the OpenShift Console using the following steps:
You will be presented with a login page to access the application. When using the default External Identity Provider (RHBK), two users (`qtodo-admin` and `qtodo-user1`) were provisioned automatically. Their initial credentials are stored in a Secret in the `keycloak-system` namespace called `keycloak-users`. You can reveal the credentials by switching to the tab containing the OpenShift Console using the following steps:

1. Select **Home** -> **Projects** from the left hand navigation bar
2. Locate and select the **keycloak-system** project
Expand Down
46 changes: 43 additions & 3 deletions values-hub.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,40 @@ clusterGroup:
project: hub
chart: hashicorp-vault
chartVersion: 0.1.*
# Custom Vault policies for least-privilege access
# Each application gets access only to its specific secrets path
#
# TWO types of policies needed:
# 1. <prefix>-k8s-secret - for Kubernetes auth (ClusterSecretStore/ExternalSecrets)
# 2. <prefix>-jwt-secret - for JWT/SPIFFE auth (application workloads)
#
# NOTE: K8s auth policies are auto-created by Ansible from vaultPrefixes
# JWT auth policies below are manually defined for apps that need direct Vault access
policies:
# ============================================================
# JWT/SPIFFE Auth Policies (for application workloads)
# These are used by apps authenticating via SPIFFE JWT tokens
# Only define policies for apps that need direct Vault access
# K8s auth policies (<prefix>-k8s-secret) are auto-created by Ansible
# ============================================================
- name: apps-qtodo-jwt-secret
policy: |
path "secret/data/apps/qtodo/*" {
capabilities = ["read"]
}
- name: hub-infra-rhtpa-jwt-secret
policy: |
path "secret/data/hub/infra/rhtpa/*" {
capabilities = ["read"]
}
- name: hub-supply-chain-jwt-secret
policy: |
path "secret/data/hub/infra/quay/*" {
capabilities = ["read"]
}
path "secret/data/hub/infra/rhtpa/rhtpa-oidc-cli" {
capabilities = ["read"]
}
jwt:
enabled: true
oidcDiscoveryUrl: https://spire-spiffe-oidc-discovery-provider.zero-trust-workload-identity-manager.svc.cluster.local
Expand All @@ -265,13 +299,19 @@ clusterGroup:
audience: qtodo
subject: spiffe://apps.{{ $.Values.global.clusterDomain }}/ns/qtodo/sa/qtodo
policies:
- global-secret
- apps-qtodo-jwt-secret
# RHTPA vault role
# - name: rhtpa
# audience: rhtpa
# subject: spiffe://apps.{{ $.Values.global.clusterDomain }}/ns/trusted-profile-analyzer/sa/rhtpa
# policies:
# - global-secret
# - hub-infra-rhtpa-jwt-secret
# Supply chain vault role (for Tekton pipelines)
# - name: supply-chain
# audience: supply-chain
# subject: spiffe://apps.{{ $.Values.global.clusterDomain }}/ns/pipeline/sa/pipeline
# policies:
# - hub-supply-chain-jwt-secret
# Shared Object Storage Backend
# Required for RHTPA and QUAY (provides S3-compatible storage via NooBaa MCG)
# NooBaa MCG provides S3-compatible object storage for multiple applications
Expand Down Expand Up @@ -403,7 +443,7 @@ clusterGroup:
- name: app.vault.role
value: qtodo
- name: app.vault.secretPath
value: secret/data/global/qtodo
value: secret/data/apps/qtodo/qtodo-db
# For Secure Supply Chain, we changed the qtodo image to use the one built in the secure supply chain
# - name: app.images.main.name
# value: quay-registry-quay-quay-enterprise.apps.{{ $.Values.global.clusterDomain }}/ztvp/qtodo
Expand Down
Loading