From 7403b244bd1c17b0a54ad14b5c1c7dd78e8e4353 Mon Sep 17 00:00:00 2001 From: Marc Parisi Date: Fri, 3 Jan 2025 06:41:48 -0500 Subject: [PATCH 01/11] dry run of gcp deploy with automated domain creation --- ops-scripts/gcp/base.sh | 3 +- ops-scripts/gcp/create-subdomain.sh | 15 ++ ops-scripts/gcp/depoloy-helm.sh | 48 +++++- ops-scripts/gcp/remove-subdomain.sh | 12 ++ ops-scripts/gcp/test-helm.sh | 35 ++++ .../templates/agent-deployment.yaml | 10 +- sentrius-gcp-chart/templates/configmap.yaml | 125 +++++++++++++- sentrius-gcp-chart/templates/deployment.yaml | 10 +- sentrius-gcp-chart/templates/ingress.yaml | 29 ++++ .../templates/keycloak-deployment.yaml | 4 +- sentrius-gcp-chart/values.yaml | 157 +++--------------- 11 files changed, 296 insertions(+), 152 deletions(-) create mode 100644 ops-scripts/gcp/create-subdomain.sh create mode 100644 ops-scripts/gcp/remove-subdomain.sh create mode 100755 ops-scripts/gcp/test-helm.sh create mode 100644 sentrius-gcp-chart/templates/ingress.yaml diff --git a/ops-scripts/gcp/base.sh b/ops-scripts/gcp/base.sh index e2c7aefc..7d0b5403 100755 --- a/ops-scripts/gcp/base.sh +++ b/ops-scripts/gcp/base.sh @@ -1,4 +1,5 @@ #!/bin/bash NAMESPACE=sentrius CLUSTER=sentrius-autopilot-cluster-1 -REGION=us-east1 \ No newline at end of file +REGION=us-east1 +ZONE=sentrius-cloud \ No newline at end of file diff --git a/ops-scripts/gcp/create-subdomain.sh b/ops-scripts/gcp/create-subdomain.sh new file mode 100644 index 00000000..c6cf9d8e --- /dev/null +++ b/ops-scripts/gcp/create-subdomain.sh @@ -0,0 +1,15 @@ +#!/bin/bash +SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) + + +source ${SCRIPT_DIR}/base.sh + +TENANT=$1 + +gcloud dns record-sets transaction start --zone=${ZONE} +gcloud dns record-sets transaction add --zone=${ZONE} \ + --name=${TENANT}.sentrius.cloud. \ + --type=CNAME \ + --ttl=300 \ + app-loadbalancer.region.cloud.goog && +gcloud dns record-sets transaction execute --zone=${ZONE} diff --git a/ops-scripts/gcp/depoloy-helm.sh b/ops-scripts/gcp/depoloy-helm.sh index 93255033..7c199152 100755 --- a/ops-scripts/gcp/depoloy-helm.sh +++ b/ops-scripts/gcp/depoloy-helm.sh @@ -6,7 +6,25 @@ SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) source ${SCRIPT_DIR}/base.sh source ${SCRIPT_DIR}/../../.gcp.env -helm upgrade --install sentrius ./sentrius-gcp-chart --namespace ${NAMESPACE} \ +TENANT=$1 + +if [[ -z "$TENANT" ]]; then + echo "Must provide single argument for tenant name" 1>&2 + exit 1 +fi + +# Check if namespace exists +kubectl get namespace ${TENANT} >/dev/null 2>&1 +if [[ $? -ne 0 ]]; then + echo "Namespace ${TENANT} does not exist. Creating..." + kubectl create namespace ${TENANT} || { echo "Failed to create namespace ${TENANT}"; exit 1; } +fi + + + +helm upgrade --install sentrius ./sentrius-gcp-chart --namespace ${TENANT} \ + --set tenant=${TENANT} \ + --set subdomain=${TENANT}.sentrius.cloud \ --set sentrius.image.repository=us-central1-docker.pkg.dev/sentrius-project/sentrius-repo/sentrius \ --set sentrius.image.tag=${SENTRIUS_VERSION} \ --set ssh.image.repository=us-central1-docker.pkg.dev/sentrius-project/sentrius-repo/sentrius-ssh \ @@ -15,3 +33,31 @@ helm upgrade --install sentrius ./sentrius-gcp-chart --namespace ${NAMESPACE} \ --set keycloak.image.tag=${SENTRIUS_KEYCLOAK_VERSION} \ --set sentriusagent.image.repository=us-central1-docker.pkg.dev/sentrius-project/sentrius-repo/sentrius-agent \ --set sentriusagent.image.tag=${SENTRIUS_AGENT_VERSION} || { echo "Failed to deploy Sentrius with Helm"; exit 1; } + + +KEYCLOAK_IP=$(kubectl get svc sentrius-keycloak -n ${TENANT} -o jsonpath='{.status.loadBalancer.ingress[0].ip}') +SENTRIUS_IP=$(kubectl get svc sentrius-sentrius -n ${TENANT} -o jsonpath='{.status.loadBalancer.ingress[0].ip}') +echo $KEYCLOAK_IP +# 35.229.32.6 +echo $SENTRIUS_IP + +# Check if subdomain exists +if gcloud dns record-sets list --zone=${ZONE} --name=${TENANT}.sentrius.cloud. | grep -q ${TENANT}.sentrius.cloud.; then + echo "Subdomain ${TENANT}.sentrius.cloud already exists. Skipping creation." +else + echo "Creating subdomain ${TENANT}.sentrius.cloud..." + gcloud dns record-sets transaction start --zone=${ZONE} + + gcloud dns record-sets transaction add --zone=${ZONE} \ + --name=${TENANT}.sentrius.cloud. \ + --type=A \ + --ttl=300 \ + $SENTRIUS_IP && + + gcloud dns record-sets transaction add --zone=${ZONE} \ + --name=keycloak.${TENANT}.sentrius.cloud. \ + --type=A \ + --ttl=300 \ + $KEYCLOAK_IP && + gcloud dns record-sets transaction execute --zone=${ZONE} +fi \ No newline at end of file diff --git a/ops-scripts/gcp/remove-subdomain.sh b/ops-scripts/gcp/remove-subdomain.sh new file mode 100644 index 00000000..40973f5c --- /dev/null +++ b/ops-scripts/gcp/remove-subdomain.sh @@ -0,0 +1,12 @@ +#!/bin/bash +SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) + + +source ${SCRIPT_DIR}/base.sh + +DOMAIN=$1 + +gcloud dns record-sets transaction start --zone=${ZONE} +gcloud dns record-sets transaction remove --zone=${ZONE} \ + --name=${DOMAIN}.sentrius.cloud --type=A --ttl=300 "192.0.2.1" +gcloud dns record-sets transaction execute --zone=${ZONE} diff --git a/ops-scripts/gcp/test-helm.sh b/ops-scripts/gcp/test-helm.sh new file mode 100755 index 00000000..9b1ba269 --- /dev/null +++ b/ops-scripts/gcp/test-helm.sh @@ -0,0 +1,35 @@ +#!/bin/bash + +SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) + + +source ${SCRIPT_DIR}/base.sh +source ${SCRIPT_DIR}/../../.gcp.env + +TENANT=$1 + +if [[ -z "$TENANT" ]]; then + echo "Must provide single argument for tenant name" 1>&2 + exit 1 +fi + +# Check if namespace exists +kubectl get namespace ${TENANT} >/dev/null 2>&1 +if [[ $? -ne 0 ]]; then + echo "Namespace ${TENANT} does not exist. Creating..." + kubectl create namespace ${TENANT} || { echo "Failed to create namespace ${TENANT}"; exit 1; } +fi + + + +helm template ${TENANT} ./sentrius-gcp-chart/ --values sentrius-gcp-chart/values.yaml \ + --set tenant=${TENANT} \ + --set subdomain=${TENANT}.sentrius.cloud \ + --set sentrius.image.repository=us-central1-docker.pkg.dev/sentrius-project/sentrius-repo/sentrius \ + --set sentrius.image.tag=${SENTRIUS_VERSION} \ + --set ssh.image.repository=us-central1-docker.pkg.dev/sentrius-project/sentrius-repo/sentrius-ssh \ + --set ssh.image.tag=${SENTRIUS_SSH_VERSION} \ + --set keycloak.image.repository=us-central1-docker.pkg.dev/sentrius-project/sentrius-repo/sentrius-keycloak \ + --set keycloak.image.tag=${SENTRIUS_KEYCLOAK_VERSION} \ + --set sentriusagent.image.repository=us-central1-docker.pkg.dev/sentrius-project/sentrius-repo/sentrius-agent \ + --set sentriusagent.image.tag=${SENTRIUS_AGENT_VERSION} || { echo "Failed to deploy Sentrius with Helm"; exit 1; } diff --git a/sentrius-gcp-chart/templates/agent-deployment.yaml b/sentrius-gcp-chart/templates/agent-deployment.yaml index ee7901d6..b0c95c5d 100644 --- a/sentrius-gcp-chart/templates/agent-deployment.yaml +++ b/sentrius-gcp-chart/templates/agent-deployment.yaml @@ -17,11 +17,13 @@ spec: initContainers: - name: wait-for-postgres image: busybox - command: [ 'sh', '-c', 'until nc -z {{ .Release.Name }}-postgres.{{ .Release.Namespace }}.svc.cluster.local 5432; do echo waiting for postgres; sleep 2; done;' ] - - name: wait-for-keycloak + command: [ 'sh', '-c', 'until nc -z {{ .Release.Name }}-postgres 5432; do echo waiting for postgres; sleep 2; done;' ] + - name: init-config image: busybox - command: [ 'sh', '-c', 'until nc -z {{ .Release.Name }}-keycloak.{{ .Release.Namespace }}.svc.cluster.local - 30081; do echo waiting for postgres; sleep 2; done;' ] + command: [ 'sh', '-c', 'cp /configmap/agent-application.properties /config/application.properties' ] + volumeMounts: + - name: config-volume + mountPath: /config containers: - name: sentrius-agent image: "{{ .Values.sentriusagent.image.repository }}:{{ .Values.sentriusagent.image.tag }}" diff --git a/sentrius-gcp-chart/templates/configmap.yaml b/sentrius-gcp-chart/templates/configmap.yaml index a76b1136..bc6d0c77 100644 --- a/sentrius-gcp-chart/templates/configmap.yaml +++ b/sentrius-gcp-chart/templates/configmap.yaml @@ -5,7 +5,126 @@ metadata: labels: {{- include "sentrius.labels" . | nindent 4 }} data: - application.properties: | - {{ .Values.sentrius.config.application | nindent 4 }} + agent-application.properties: | + keystore.file=sso.jceks + keystore.password=${KEYSTORE_PASSWORD} + keystore.alias=KEYBOX-ENCRYPTION_KEY + keystore.algorithm=AES + spring.main.web-application-type=servlet + spring.thymeleaf.enabled=true + spring.freemarker.enabled=false + #flyway configuration + spring.flyway.enabled=true + spring.datasource.url=jdbc:postgresql://sentrius-postgres:5432/sentrius + spring.datasource.username=${SPRING_DATASOURCE_USERNAME} + spring.datasource.password=${SPRING_DATASOURCE_PASSWORD} + spring.datasource.driver-class-name=org.postgresql.Driver + # Connection pool settings + spring.datasource.hikari.maximum-pool-size=10 + spring.datasource.hikari.minimum-idle=5 + spring.datasource.hikari.idle-timeout=30000 + spring.datasource.hikari.max-lifetime=1800000 + # Hibernate settings (optional, for JPA) + spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect + # Disable automatic schema generation in production + spring.jpa.hibernate.ddl-auto=none + # Ensure this path matches your project structure + #spring.flyway.locations=classpath:db/migration/ + spring.flyway.baseline-on-migrate=true + # Thymeleaf settings + spring.thymeleaf.prefix=classpath:/templates/ + spring.thymeleaf.suffix=.html + #spring.datasource.url=jdbc:h2:mem:testdb + logging.level.org.springframework.web=INFO + logging.level.org.springframework.security=INFO + logging.level.io.sentrius=DEBUG + logging.level.org.thymeleaf=INFO + spring.thymeleaf.servlet.produce-partial-output-while-processing=false + spring.servlet.multipart.enabled=true + spring.servlet.multipart.max-file-size=10MB + spring.servlet.multipart.max-request-size=10MB + server.error.whitelabel.enabled=false + dynamic.properties.path=/config/dynamic.properties + keycloak.realm=sentrius + # Keycloak configuration + spring.security.oauth2.client.registration.keycloak.client-id="{{ .Values.sentrius.oauth2.client_id }}" + spring.security.oauth2.client.registration.keycloak.client-secret="{{ .Values.sentrius.oauth2.client_secret }}" + spring.security.oauth2.client.registration.keycloak.authorization-grant-type="{{ .Values.sentrius.oauth2.authorization_grant_type }}" + spring.security.oauth2.client.registration.keycloak.redirect-uri="{{ .Values.sentrius.oauth2.redirect_uri }}" + spring.security.oauth2.client.registration.keycloak.scope="{{ .Values.sentrius.oauth2.scope }}" + spring.security.oauth2.resourceserver.jwt.issuer-uri="{{ .Values.sentrius.oauth2.issuer_uri }}" + spring.security.oauth2.client.provider.keycloak.issuer-uri=http://keycloak.{{ .Values.tenant }}.sentrius.cloud/realms/sentrius + agents.session-analytics.enabled=true + api-application.properties: | + keystore.file=sso.jceks + keystore.password=${KEYSTORE_PASSWORD} + keystore.alias=KEYBOX-ENCRYPTION_KEY + keystore.algorithm=AES + spring.main.web-application-type=servlet + spring.thymeleaf.enabled=true + spring.freemarker.enabled=false + #flyway configuration + spring.flyway.enabled=true + spring.datasource.url=jdbc:postgresql://sentrius-postgres:5432/sentrius + spring.datasource.username=${SPRING_DATASOURCE_USERNAME} + spring.datasource.password=${SPRING_DATASOURCE_PASSWORD} + spring.datasource.driver-class-name=org.postgresql.Driver + # Connection pool settings + spring.datasource.hikari.maximum-pool-size=10 + spring.datasource.hikari.minimum-idle=5 + spring.datasource.hikari.idle-timeout=30000 + spring.datasource.hikari.max-lifetime=1800000 + # Hibernate settings (optional, for JPA) + spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect + # Disable automatic schema generation in production + spring.jpa.hibernate.ddl-auto=none + # Ensure this path matches your project structure + #spring.flyway.locations=classpath:db/migration/ + spring.flyway.baseline-on-migrate=true + # Thymeleaf settings + spring.thymeleaf.prefix=classpath:/templates/ + spring.thymeleaf.suffix=.html + #spring.datasource.url=jdbc:h2:mem:testdb + logging.level.org.springframework.web=INFO + logging.level.org.springframework.security=INFO + logging.level.io.sentrius=DEBUG + logging.level.org.thymeleaf=INFO + spring.thymeleaf.servlet.produce-partial-output-while-processing=false + spring.servlet.multipart.enabled=true + spring.servlet.multipart.max-file-size=10MB + spring.servlet.multipart.max-request-size=10MB + server.error.whitelabel.enabled=false + dynamic.properties.path=/config/dynamic.properties + keycloak.realm=sentrius + # Keycloak configuration + spring.security.oauth2.client.registration.keycloak.client-id={{ .Values.sentrius.oauth2.client_id }} + spring.security.oauth2.client.registration.keycloak.client-secret={{ .Values.sentrius.oauth2.client_secret }} + spring.security.oauth2.client.registration.keycloak.authorization-grant-type={{ .Values.sentrius.oauth2.authorization_grant_type }} + spring.security.oauth2.client.registration.keycloak.redirect-uri={{ .Values.sentrius.oauth2.redirect_uri }} + spring.security.oauth2.client.registration.keycloak.scope={{ .Values.sentrius.oauth2.scope }} + spring.security.oauth2.resourceserver.jwt.issuer-uri={{ .Values.sentrius.oauth2.issuer_uri }} + spring.security.oauth2.client.provider.keycloak.issuer-uri=http://keycloak.{{ .Values.tenant }}.sentrius.cloud/realms/sentrius dynamic.properties: | - {{ .Values.sentrius.config.dynamic | nindent 4 }} + auditorClass=io.sentrius.sso.automation.auditing.AccessTokenAuditor + twopartyapproval.option.LOCKING_SYSTEMS=true + requireProfileForLogin=true + maxJitDurationMs=1440000 + sshEnabled=true + systemLogoName=Sentrius + AccessTokenAuditor.rule.4=io.sentrius.sso.automation.auditing.rules.OpenAISessionRule;Malicious AI Monitoring + AccessTokenAuditor.rule.5=io.sentrius.sso.automation.auditing.rules.TwoPartyAIMonitor;AI Second Party Monitor + allowProxies=true + AccessTokenAuditor.rule.2=io.sentrius.sso.automation.auditing.rules.DeletePrevention;Delete Prevention + AccessTokenAuditor.rule.3=io.sentrius.sso.automation.auditing.rules.TwoPartySessionRule;Require Second Party Monitoring + AccessTokenAuditor.rule.0=io.sentrius.sso.automation.auditing.rules.CommandEvaluator;Restricted Commands + terminalsInNewTab=false + auditFlushIntervalMs=5000 + AccessTokenAuditor.rule.1=io.sentrius.sso.automation.auditing.rules.AllowedCommandsRule;Approved Commands + knownHostsPath=/home/marc/.ssh/known_hosts + systemLogoPathLarge=/images/sentrius_large.jpg + maxJitUses=1 + systemLogoPathSmall=/images/sentrius_small.png + enableInternalAudit=true + twopartyapproval.require.explanation.LOCKING_SYSTEMS=false + canApproveOwnJITs=false + yamlConfiguration=/app/exampleInstallWithTypes.yml diff --git a/sentrius-gcp-chart/templates/deployment.yaml b/sentrius-gcp-chart/templates/deployment.yaml index c551c946..bf45d795 100644 --- a/sentrius-gcp-chart/templates/deployment.yaml +++ b/sentrius-gcp-chart/templates/deployment.yaml @@ -17,11 +17,13 @@ spec: initContainers: - name: wait-for-postgres image: busybox - command: [ 'sh', '-c', 'until nc -z {{ .Release.Name }}-postgres.{{ .Release.Namespace }}.svc.cluster.local 5432; do echo waiting for postgres; sleep 2; done;' ] - - name: wait-for-keycloak + command: [ 'sh', '-c', 'until nc -z {{ .Release.Name }}-postgres 5432; do echo waiting for postgres; sleep 2; done;' ] + - name: init-config image: busybox - command: [ 'sh', '-c', 'until nc -z {{ .Release.Name }}-keycloak.{{ .Release.Namespace }}.svc.cluster.local - 30081; do echo waiting for postgres; sleep 2; done;' ] + command: [ 'sh', '-c', 'cp /configmap/api-application.properties /config/application.properties' ] + volumeMounts: + - name: config-volume + mountPath: /config containers: - name: sentrius image: "{{ .Values.sentrius.image.repository }}:{{ .Values.sentrius.image.tag }}" diff --git a/sentrius-gcp-chart/templates/ingress.yaml b/sentrius-gcp-chart/templates/ingress.yaml new file mode 100644 index 00000000..0d8c0968 --- /dev/null +++ b/sentrius-gcp-chart/templates/ingress.yaml @@ -0,0 +1,29 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: ingress-{{ .Values.tenant }} + namespace: {{ .Release.Namespace }} + annotations: + kubernetes.io/ingress.class: "gce" +spec: + rules: + - host: keycloak.{{ .Values.tenant }}.sentrius.cloud + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: keycloak + port: + number: 8081 + - host: {{ .Values.tenant }}.sentrius.cloud + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: sentrius + port: + number: 8080 diff --git a/sentrius-gcp-chart/templates/keycloak-deployment.yaml b/sentrius-gcp-chart/templates/keycloak-deployment.yaml index 7fdd24f4..c336dbfe 100644 --- a/sentrius-gcp-chart/templates/keycloak-deployment.yaml +++ b/sentrius-gcp-chart/templates/keycloak-deployment.yaml @@ -22,10 +22,10 @@ spec: image: "{{ .Values.keycloak.image.repository }}:{{ .Values.keycloak.image.tag }}" imagePullPolicy: "{{ .Values.keycloak.image.pullPolicy }}" ports: - - containerPort: 30081 + - containerPort: 8081 env: - name: KC_HTTP_PORT - value: "30081" + value: "8081" - name: KEYCLOAK_ADMIN value: {{ .Values.keycloak.adminUser }} - name: KEYCLOAK_ADMIN_PASSWORD diff --git a/sentrius-gcp-chart/values.yaml b/sentrius-gcp-chart/values.yaml index 31e71459..aeb3ed3a 100644 --- a/sentrius-gcp-chart/values.yaml +++ b/sentrius-gcp-chart/values.yaml @@ -2,6 +2,10 @@ replicaCount: 1 namespace: default + +tenant: sentrius-demo +subdomain: "{{ .Values.tenant }}.sentrius.cloud" + # Sentrius configuration sentrius: image: @@ -16,80 +20,13 @@ sentrius: SPRING_DATASOURCE_PASSWORD: password KEYSTORE_PASSWORD: sentrius resources: {} - config: - application: | - keystore.file=sso.jceks - keystore.password=${KEYSTORE_PASSWORD} - keystore.alias=KEYBOX-ENCRYPTION_KEY - keystore.algorithm=AES - spring.main.web-application-type=servlet - spring.thymeleaf.enabled=true - spring.freemarker.enabled=false - #flyway configuration - spring.flyway.enabled=true - spring.datasource.url=jdbc:postgresql://sentrius-postgres:5432/sentrius - spring.datasource.username=${SPRING_DATASOURCE_USERNAME} - spring.datasource.password=${SPRING_DATASOURCE_PASSWORD} - spring.datasource.driver-class-name=org.postgresql.Driver - # Connection pool settings - spring.datasource.hikari.maximum-pool-size=10 - spring.datasource.hikari.minimum-idle=5 - spring.datasource.hikari.idle-timeout=30000 - spring.datasource.hikari.max-lifetime=1800000 - # Hibernate settings (optional, for JPA) - spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect - # Disable automatic schema generation in production - spring.jpa.hibernate.ddl-auto=none - # Ensure this path matches your project structure - #spring.flyway.locations=classpath:db/migration/ - spring.flyway.baseline-on-migrate=true - # Thymeleaf settings - spring.thymeleaf.prefix=classpath:/templates/ - spring.thymeleaf.suffix=.html - #spring.datasource.url=jdbc:h2:mem:testdb - logging.level.org.springframework.web=INFO - logging.level.org.springframework.security=INFO - logging.level.io.sentrius=DEBUG - logging.level.org.thymeleaf=INFO - spring.thymeleaf.servlet.produce-partial-output-while-processing=false - spring.servlet.multipart.enabled=true - spring.servlet.multipart.max-file-size=10MB - spring.servlet.multipart.max-request-size=10MB - server.error.whitelabel.enabled=false - dynamic.properties.path=/config/dynamic.properties - keycloak.realm=sentrius - # keycloak configuration - spring.security.oauth2.client.registration.keycloak.client-id=sentrius-api - spring.security.oauth2.client.registration.keycloak.client-secret=nGkEukexSWTvDzYjSkDmeUlM0FJ5Jhh0 - spring.security.oauth2.client.registration.keycloak.authorization-grant-type=authorization_code - spring.security.oauth2.client.registration.keycloak.redirect-uri=http://sentrius-keycloak:30080/login/oauth2/code/keycloak - spring.security.oauth2.client.registration.keycloak.scope=openid,profile,email - spring.security.oauth2.resourceserver.jwt.issuer-uri=http://sentrius-keycloak:30081/realms/sentrius - spring.security.oauth2.client.provider.keycloak.issuer-uri=http://sentrius-keycloak:30081/realms/sentrius - dynamic: | - auditorClass=io.sentrius.sso.automation.auditing.AccessTokenAuditor - twopartyapproval.option.LOCKING_SYSTEMS=true - requireProfileForLogin=true - maxJitDurationMs=1440000 - sshEnabled=true - systemLogoName=Sentrius - AccessTokenAuditor.rule.4=io.sentrius.sso.automation.auditing.rules.OpenAISessionRule;Malicious AI Monitoring - AccessTokenAuditor.rule.5=io.sentrius.sso.automation.auditing.rules.TwoPartyAIMonitor;AI Second Party Monitor - allowProxies=true - AccessTokenAuditor.rule.2=io.sentrius.sso.automation.auditing.rules.DeletePrevention;Delete Prevention - AccessTokenAuditor.rule.3=io.sentrius.sso.automation.auditing.rules.TwoPartySessionRule;Require Second Party Monitoring - AccessTokenAuditor.rule.0=io.sentrius.sso.automation.auditing.rules.CommandEvaluator;Restricted Commands - terminalsInNewTab=false - auditFlushIntervalMs=5000 - AccessTokenAuditor.rule.1=io.sentrius.sso.automation.auditing.rules.AllowedCommandsRule;Approved Commands - knownHostsPath=/home/marc/.ssh/known_hosts - systemLogoPathLarge=/images/sentrius_large.jpg - maxJitUses=1 - systemLogoPathSmall=/images/sentrius_small.png - enableInternalAudit=true - twopartyapproval.require.explanation.LOCKING_SYSTEMS=false - canApproveOwnJITs=false - yamlConfiguration=/app/exampleInstallWithTypes.yml + oauth2: + client_id: sentrius-api + client_secret: nGkEukexSWTvDzYjSkDmeUlM0FJ5Jhh0 + authorization_grant_type: authorization_code + redirect_uri: http://{{ .Values.subdomain }}/login/oauth2/code/keycloak + scope: openid,profile,email + issuer_uri: http://keycloak.{{ .Values.subdomain }}/realms/sentrius sentriusagent: service: @@ -99,6 +36,13 @@ sentriusagent: repository: sentrius-agent pullPolicy: IfNotPresent port: 8080 + oauth2: + client_id: sentrius-api + client_secret: nGkEukexSWTvDzYjSkDmeUlM0FJ5Jhh0 + authorization_grant_type: authorization_code + redirect-uri: http://{{ .Values.subdomain }}/login/oauth2/code/keycloak + scope: openid,profile,email + issuer-uri: http://keycloak.{{ .Values.subdomain }}/realms/sentrius ssh: port: 22 env: @@ -108,55 +52,7 @@ sentriusagent: resources: {} config: application: | - keystore.file=sso.jceks - keystore.password=${KEYSTORE_PASSWORD} - keystore.alias=KEYBOX-ENCRYPTION_KEY - keystore.algorithm=AES - spring.main.web-application-type=servlet - spring.thymeleaf.enabled=true - spring.freemarker.enabled=false - #flyway configuration - spring.flyway.enabled=true - spring.datasource.url=jdbc:postgresql://sentrius-postgres:5432/sentrius - spring.datasource.username=${SPRING_DATASOURCE_USERNAME} - spring.datasource.password=${SPRING_DATASOURCE_PASSWORD} - spring.datasource.driver-class-name=org.postgresql.Driver - # Connection pool settings - spring.datasource.hikari.maximum-pool-size=10 - spring.datasource.hikari.minimum-idle=5 - spring.datasource.hikari.idle-timeout=30000 - spring.datasource.hikari.max-lifetime=1800000 - # Hibernate settings (optional, for JPA) - spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect - # Disable automatic schema generation in production - spring.jpa.hibernate.ddl-auto=none - # Ensure this path matches your project structure - #spring.flyway.locations=classpath:db/migration/ - spring.flyway.baseline-on-migrate=true - # Thymeleaf settings - spring.thymeleaf.prefix=classpath:/templates/ - spring.thymeleaf.suffix=.html - #spring.datasource.url=jdbc:h2:mem:testdb - logging.level.org.springframework.web=INFO - logging.level.org.springframework.security=INFO - logging.level.io.sentrius=DEBUG - logging.level.org.thymeleaf=INFO - spring.thymeleaf.servlet.produce-partial-output-while-processing=false - spring.servlet.multipart.enabled=true - spring.servlet.multipart.max-file-size=10MB - spring.servlet.multipart.max-request-size=10MB - server.error.whitelabel.enabled=false - dynamic.properties.path=/config/dynamic.properties - keycloak.realm=sentrius - # keycloak configuration - spring.security.oauth2.client.registration.keycloak.client-id=sentrius-api - spring.security.oauth2.client.registration.keycloak.client-secret=nGkEukexSWTvDzYjSkDmeUlM0FJ5Jhh0 - spring.security.oauth2.client.registration.keycloak.authorization-grant-type=authorization_code - spring.security.oauth2.client.registration.keycloak.redirect-uri=http://sentrius-keycloak:30080/login/oauth2/code/keycloak - spring.security.oauth2.client.registration.keycloak.scope=openid,profile,email - spring.security.oauth2.resourceserver.jwt.issuer-uri=http://sentrius-keycloak:30081/realms/sentrius - spring.security.oauth2.client.provider.keycloak.issuer-uri=http://sentrius-keycloak:30081/realms/sentrius - agents.session-analytics.enabled=true + # PostgreSQL configuration postgres: @@ -186,19 +82,6 @@ secrets: password: cGFzc3dvcmQ= # password keystorePassword: c2VudHJpdXM= # sentrius -# Service settings -service: - type: NodePort - nodePort: 30080 - - - -# MetalLB (optional) -metallb: - enabled: true - addressPool: - - 192.168.122.100-192.168.122.110 - keycloak: image: repository: sentrius-keycloak @@ -206,7 +89,7 @@ keycloak: host: keycloak.default.svc.cluster.local adminUser: admin adminPassword: admin - port: 8080 + port: 8081 db: image: postgres:15 user: keycloak From 47e72677eb14a6bec8e995055adfbd1390de2099 Mon Sep 17 00:00:00 2001 From: Marc Parisi Date: Fri, 3 Jan 2025 17:43:55 -0500 Subject: [PATCH 02/11] minor updates --- .gcp.env | 6 +++--- Dockerfile | 2 +- docker/keycloak/realms/sentrius-realm.json | 6 +++--- docker/sentrius-agent/Dockerfile | 2 +- ops-scripts/gcp/remove-subdomain.sh | 2 +- sentrius-gcp-chart/templates/agent-deployment.yaml | 6 ------ sentrius-gcp-chart/templates/configmap.yaml | 8 ++++---- sentrius-gcp-chart/templates/deployment.yaml | 6 ------ .../templates/keycloak-deployment.yaml | 12 +++++++++++- sentrius-gcp-chart/values.yaml | 3 ++- 10 files changed, 26 insertions(+), 27 deletions(-) diff --git a/.gcp.env b/.gcp.env index 1ec2a730..d4c2f87c 100644 --- a/.gcp.env +++ b/.gcp.env @@ -1,4 +1,4 @@ -SENTRIUS_VERSION=1.0.9 +SENTRIUS_VERSION=1.0.10 SENTRIUS_SSH_VERSION=1.0.2 -SENTRIUS_KEYCLOAK_VERSION=1.0.2 -SENTRIUS_AGENT_VERSION=1.0.10 \ No newline at end of file +SENTRIUS_KEYCLOAK_VERSION=1.0.3 +SENTRIUS_AGENT_VERSION=1.0.11 \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 25cbaf1d..f3056b56 100644 --- a/Dockerfile +++ b/Dockerfile @@ -15,4 +15,4 @@ RUN apt-get update && apt-get install -y curl # Command to run the app -CMD ["java", "-jar", "/app/sentrius.jar", "--spring.config.location=/config/application.properties", "--dynamic.properties.path=/config/dynamic.properties"] +CMD ["java", "-jar", "/app/sentrius.jar", "--spring.config.location=/config/api-application.properties", "--dynamic.properties.path=/config/dynamic.properties"] diff --git a/docker/keycloak/realms/sentrius-realm.json b/docker/keycloak/realms/sentrius-realm.json index b2de8013..d257796e 100644 --- a/docker/keycloak/realms/sentrius-realm.json +++ b/docker/keycloak/realms/sentrius-realm.json @@ -7,9 +7,9 @@ "enabled": true, "clientAuthenticatorType": "client-secret", "secret": "nGkEukexSWTvDzYjSkDmeUlM0FJ5Jhh0", - "rootUrl": "http://sentrius-keycloak:30080/", - "baseUrl": "http://sentrius-keycloak:30080/", - "redirectUris": ["http://sentrius-keycloak:30080/*"], + "rootUrl": "${ROOT_URL}", + "baseUrl": "/", + "redirectUris": ["${REDIRECT_URIS}/*"], "protocol": "openid-connect" } ], diff --git a/docker/sentrius-agent/Dockerfile b/docker/sentrius-agent/Dockerfile index dd154a91..789755a1 100644 --- a/docker/sentrius-agent/Dockerfile +++ b/docker/sentrius-agent/Dockerfile @@ -14,4 +14,4 @@ RUN apt-get update && apt-get install -y curl # Command to run the app -CMD ["java", "-jar", "/app/agent.jar", "--spring.config.location=/config/application.properties"] +CMD ["java", "-jar", "/app/agent.jar", "--spring.config.location=/config/agent-application.properties"] diff --git a/ops-scripts/gcp/remove-subdomain.sh b/ops-scripts/gcp/remove-subdomain.sh index 40973f5c..fa7f4b20 100644 --- a/ops-scripts/gcp/remove-subdomain.sh +++ b/ops-scripts/gcp/remove-subdomain.sh @@ -8,5 +8,5 @@ DOMAIN=$1 gcloud dns record-sets transaction start --zone=${ZONE} gcloud dns record-sets transaction remove --zone=${ZONE} \ - --name=${DOMAIN}.sentrius.cloud --type=A --ttl=300 "192.0.2.1" + --name=${DOMAIN}.sentrius.cloud --type=A --ttl=300 gcloud dns record-sets transaction execute --zone=${ZONE} diff --git a/sentrius-gcp-chart/templates/agent-deployment.yaml b/sentrius-gcp-chart/templates/agent-deployment.yaml index b0c95c5d..c39dd149 100644 --- a/sentrius-gcp-chart/templates/agent-deployment.yaml +++ b/sentrius-gcp-chart/templates/agent-deployment.yaml @@ -18,12 +18,6 @@ spec: - name: wait-for-postgres image: busybox command: [ 'sh', '-c', 'until nc -z {{ .Release.Name }}-postgres 5432; do echo waiting for postgres; sleep 2; done;' ] - - name: init-config - image: busybox - command: [ 'sh', '-c', 'cp /configmap/agent-application.properties /config/application.properties' ] - volumeMounts: - - name: config-volume - mountPath: /config containers: - name: sentrius-agent image: "{{ .Values.sentriusagent.image.repository }}:{{ .Values.sentriusagent.image.tag }}" diff --git a/sentrius-gcp-chart/templates/configmap.yaml b/sentrius-gcp-chart/templates/configmap.yaml index bc6d0c77..9e6231dd 100644 --- a/sentrius-gcp-chart/templates/configmap.yaml +++ b/sentrius-gcp-chart/templates/configmap.yaml @@ -50,9 +50,9 @@ data: spring.security.oauth2.client.registration.keycloak.client-id="{{ .Values.sentrius.oauth2.client_id }}" spring.security.oauth2.client.registration.keycloak.client-secret="{{ .Values.sentrius.oauth2.client_secret }}" spring.security.oauth2.client.registration.keycloak.authorization-grant-type="{{ .Values.sentrius.oauth2.authorization_grant_type }}" - spring.security.oauth2.client.registration.keycloak.redirect-uri="{{ .Values.sentrius.oauth2.redirect_uri }}" + spring.security.oauth2.client.registration.keycloak.redirect-uri=http://{{ .Values.subdomain }}/login/oauth2/code/keycloak spring.security.oauth2.client.registration.keycloak.scope="{{ .Values.sentrius.oauth2.scope }}" - spring.security.oauth2.resourceserver.jwt.issuer-uri="{{ .Values.sentrius.oauth2.issuer_uri }}" + spring.security.oauth2.resourceserver.jwt.issuer-uri=http://keycloak.{{ .Values.subdomain }}/realms/sentrius spring.security.oauth2.client.provider.keycloak.issuer-uri=http://keycloak.{{ .Values.tenant }}.sentrius.cloud/realms/sentrius agents.session-analytics.enabled=true api-application.properties: | @@ -100,9 +100,9 @@ data: spring.security.oauth2.client.registration.keycloak.client-id={{ .Values.sentrius.oauth2.client_id }} spring.security.oauth2.client.registration.keycloak.client-secret={{ .Values.sentrius.oauth2.client_secret }} spring.security.oauth2.client.registration.keycloak.authorization-grant-type={{ .Values.sentrius.oauth2.authorization_grant_type }} - spring.security.oauth2.client.registration.keycloak.redirect-uri={{ .Values.sentrius.oauth2.redirect_uri }} + spring.security.oauth2.client.registration.keycloak.redirect-uri=http://{{ .Values.subdomain }}/login/oauth2/code/keycloak spring.security.oauth2.client.registration.keycloak.scope={{ .Values.sentrius.oauth2.scope }} - spring.security.oauth2.resourceserver.jwt.issuer-uri={{ .Values.sentrius.oauth2.issuer_uri }} + spring.security.oauth2.resourceserver.jwt.issuer-uri=http://keycloak.{{ .Values.subdomain }}/realms/sentrius spring.security.oauth2.client.provider.keycloak.issuer-uri=http://keycloak.{{ .Values.tenant }}.sentrius.cloud/realms/sentrius dynamic.properties: | auditorClass=io.sentrius.sso.automation.auditing.AccessTokenAuditor diff --git a/sentrius-gcp-chart/templates/deployment.yaml b/sentrius-gcp-chart/templates/deployment.yaml index bf45d795..861c0d41 100644 --- a/sentrius-gcp-chart/templates/deployment.yaml +++ b/sentrius-gcp-chart/templates/deployment.yaml @@ -18,12 +18,6 @@ spec: - name: wait-for-postgres image: busybox command: [ 'sh', '-c', 'until nc -z {{ .Release.Name }}-postgres 5432; do echo waiting for postgres; sleep 2; done;' ] - - name: init-config - image: busybox - command: [ 'sh', '-c', 'cp /configmap/api-application.properties /config/application.properties' ] - volumeMounts: - - name: config-volume - mountPath: /config containers: - name: sentrius image: "{{ .Values.sentrius.image.repository }}:{{ .Values.sentrius.image.tag }}" diff --git a/sentrius-gcp-chart/templates/keycloak-deployment.yaml b/sentrius-gcp-chart/templates/keycloak-deployment.yaml index c336dbfe..57231199 100644 --- a/sentrius-gcp-chart/templates/keycloak-deployment.yaml +++ b/sentrius-gcp-chart/templates/keycloak-deployment.yaml @@ -41,12 +41,22 @@ spec: - name: KC_DB_PASSWORD value: {{ .Values.keycloak.db.password }} - name: KC_HOSTNAME - value: {{ .Values.keycloak.hostname }}:30081 + value: keycloak.{{ .Values.subdomain }} - name: KC_HOSTNAME_STRICT value: "false" - name: KEYCLOAK_LOGLEVEL value: DEBUG - name: ROOT_LOGLEVEL value: DEBUG + - name: ROOT_URL + value: http://{{ .Values.subdomain }}/ + - name: REDIRECT_URIS + value: http://{{ .Values.subdomain }} + - name: PROXY_ADDRESS_FORWARDING + value: "true" + - name: KC_HOSTNAME_STRICT_HTTPS + value: "false" + - name: KC_HTTP_ENABLED + value: "true" command: [ "/opt/keycloak/bin/kc.sh" ] args: [ "start-dev", "--proxy=edge", "--import-realm"] diff --git a/sentrius-gcp-chart/values.yaml b/sentrius-gcp-chart/values.yaml index aeb3ed3a..ffad6ae1 100644 --- a/sentrius-gcp-chart/values.yaml +++ b/sentrius-gcp-chart/values.yaml @@ -96,5 +96,6 @@ keycloak: password: password database: keycloak replicas: 1 - hostname: sentrius-keycloak + #hostname: sentrius-keycloak + From 4346659de79e52f8f36c4337562b44c545f7ce7e Mon Sep 17 00:00:00 2001 From: Marc Parisi Date: Sat, 4 Jan 2025 06:14:27 -0500 Subject: [PATCH 03/11] Make it simpler to create the domain --- ops-scripts/gcp/depoloy-helm.sh | 33 ++++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/ops-scripts/gcp/depoloy-helm.sh b/ops-scripts/gcp/depoloy-helm.sh index 7c199152..c4a456d0 100755 --- a/ops-scripts/gcp/depoloy-helm.sh +++ b/ops-scripts/gcp/depoloy-helm.sh @@ -35,11 +35,29 @@ helm upgrade --install sentrius ./sentrius-gcp-chart --namespace ${TENANT} \ --set sentriusagent.image.tag=${SENTRIUS_AGENT_VERSION} || { echo "Failed to deploy Sentrius with Helm"; exit 1; } -KEYCLOAK_IP=$(kubectl get svc sentrius-keycloak -n ${TENANT} -o jsonpath='{.status.loadBalancer.ingress[0].ip}') -SENTRIUS_IP=$(kubectl get svc sentrius-sentrius -n ${TENANT} -o jsonpath='{.status.loadBalancer.ingress[0].ip}') -echo $KEYCLOAK_IP -# 35.229.32.6 -echo $SENTRIUS_IP +# Wait for LoadBalancer IPs to be ready +echo "Waiting for LoadBalancer IPs to be assigned..." +RETRIES=30 +SLEEP_INTERVAL=10 + +for ((i=1; i<=RETRIES; i++)); do + KEYCLOAK_IP=$(kubectl get svc sentrius-keycloak -n ${TENANT} -o jsonpath='{.status.loadBalancer.ingress[0].ip}' 2>/dev/null) + SENTRIUS_IP=$(kubectl get svc sentrius-sentrius -n ${TENANT} -o jsonpath='{.status.loadBalancer.ingress[0].ip}' 2>/dev/null) + + if [[ -n "$KEYCLOAK_IP" && -n "$SENTRIUS_IP" ]]; then + echo "Keycloak IP: $KEYCLOAK_IP" + echo "Sentrius IP: $SENTRIUS_IP" + break + fi + + echo "Attempt $i: Waiting for IPs to be assigned..." + sleep $SLEEP_INTERVAL +done + +if [[ -z "$KEYCLOAK_IP" || -z "$SENTRIUS_IP" ]]; then + echo "Failed to retrieve LoadBalancer IPs after $((RETRIES * SLEEP_INTERVAL)) seconds." + exit 1 +fi # Check if subdomain exists if gcloud dns record-sets list --zone=${ZONE} --name=${TENANT}.sentrius.cloud. | grep -q ${TENANT}.sentrius.cloud.; then @@ -52,12 +70,13 @@ else --name=${TENANT}.sentrius.cloud. \ --type=A \ --ttl=300 \ - $SENTRIUS_IP && + $SENTRIUS_IP gcloud dns record-sets transaction add --zone=${ZONE} \ --name=keycloak.${TENANT}.sentrius.cloud. \ --type=A \ --ttl=300 \ - $KEYCLOAK_IP && + $KEYCLOAK_IP + gcloud dns record-sets transaction execute --zone=${ZONE} fi \ No newline at end of file From bc4c3dfe7c4e49c94349a2061f333bfe29149dc5 Mon Sep 17 00:00:00 2001 From: Marc Parisi Date: Sat, 4 Jan 2025 07:01:50 -0500 Subject: [PATCH 04/11] Add managed certificate ( did not work yet) --- sentrius-gcp-chart/templates/ingress.yaml | 7 ++++++- sentrius-gcp-chart/templates/managed-certificate.yaml | 9 +++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 sentrius-gcp-chart/templates/managed-certificate.yaml diff --git a/sentrius-gcp-chart/templates/ingress.yaml b/sentrius-gcp-chart/templates/ingress.yaml index 0d8c0968..aa2d2578 100644 --- a/sentrius-gcp-chart/templates/ingress.yaml +++ b/sentrius-gcp-chart/templates/ingress.yaml @@ -6,6 +6,11 @@ metadata: annotations: kubernetes.io/ingress.class: "gce" spec: + tls: + - hosts: + - {{ .Values.tenant }}.sentrius.cloud + - keycloak.{{ .Values.tenant }}.sentrius.cloud + secretName: {{ .Values.tenant }}-tls rules: - host: keycloak.{{ .Values.tenant }}.sentrius.cloud http: @@ -14,7 +19,7 @@ spec: pathType: Prefix backend: service: - name: keycloak + name: sentrius-keycloak port: number: 8081 - host: {{ .Values.tenant }}.sentrius.cloud diff --git a/sentrius-gcp-chart/templates/managed-certificate.yaml b/sentrius-gcp-chart/templates/managed-certificate.yaml new file mode 100644 index 00000000..a7c33b59 --- /dev/null +++ b/sentrius-gcp-chart/templates/managed-certificate.yaml @@ -0,0 +1,9 @@ +apiVersion: networking.gke.io/v1 +kind: ManagedCertificate +metadata: + name: keycloak-cert + namespace: {{ .Values.tenant }} +spec: + domains: + - {{ .Values.subdomain }} + - keycloak.{{ .Values.subdomain }} From 9e25b657f43a270baeff275092908bfe34787f11 Mon Sep 17 00:00:00 2001 From: Marc Parisi Date: Mon, 6 Jan 2025 15:51:59 -0500 Subject: [PATCH 05/11] what the hell --- ops-scripts/gcp/depoloy-helm.sh | 17 +++++++++-------- sentrius-gcp-chart/templates/ingress.yaml | 17 +++++++---------- .../templates/keycloak-service.yaml | 4 ++-- sentrius-gcp-chart/templates/managed-cert.yaml | 8 ++++++++ .../templates/managed-certificate.yaml | 9 --------- sentrius-gcp-chart/templates/service.yaml | 4 ++-- 6 files changed, 28 insertions(+), 31 deletions(-) create mode 100644 sentrius-gcp-chart/templates/managed-cert.yaml delete mode 100644 sentrius-gcp-chart/templates/managed-certificate.yaml diff --git a/ops-scripts/gcp/depoloy-helm.sh b/ops-scripts/gcp/depoloy-helm.sh index c4a456d0..f5de5720 100755 --- a/ops-scripts/gcp/depoloy-helm.sh +++ b/ops-scripts/gcp/depoloy-helm.sh @@ -41,12 +41,13 @@ RETRIES=30 SLEEP_INTERVAL=10 for ((i=1; i<=RETRIES; i++)); do - KEYCLOAK_IP=$(kubectl get svc sentrius-keycloak -n ${TENANT} -o jsonpath='{.status.loadBalancer.ingress[0].ip}' 2>/dev/null) - SENTRIUS_IP=$(kubectl get svc sentrius-sentrius -n ${TENANT} -o jsonpath='{.status.loadBalancer.ingress[0].ip}' 2>/dev/null) + # Retrieve LoadBalancer IP + # Retrieve LoadBalancer IP + INGRESS_IP=$(kubectl get ingress managed-cert-ingress-${TENANT} -n ${TENANT} -o jsonpath='{.status.loadBalancer.ingress[0].ip}') - if [[ -n "$KEYCLOAK_IP" && -n "$SENTRIUS_IP" ]]; then - echo "Keycloak IP: $KEYCLOAK_IP" - echo "Sentrius IP: $SENTRIUS_IP" + + if [[ -n "INGRESS_IP" ]]; then + echo "INGRESS_IP IP: $INGRESS_IP" break fi @@ -54,7 +55,7 @@ for ((i=1; i<=RETRIES; i++)); do sleep $SLEEP_INTERVAL done -if [[ -z "$KEYCLOAK_IP" || -z "$SENTRIUS_IP" ]]; then +if [[ -z "INGRESS_IP" ]]; then echo "Failed to retrieve LoadBalancer IPs after $((RETRIES * SLEEP_INTERVAL)) seconds." exit 1 fi @@ -70,13 +71,13 @@ else --name=${TENANT}.sentrius.cloud. \ --type=A \ --ttl=300 \ - $SENTRIUS_IP + $NGRESS_IP gcloud dns record-sets transaction add --zone=${ZONE} \ --name=keycloak.${TENANT}.sentrius.cloud. \ --type=A \ --ttl=300 \ - $KEYCLOAK_IP + $INGRESS_IP gcloud dns record-sets transaction execute --zone=${ZONE} fi \ No newline at end of file diff --git a/sentrius-gcp-chart/templates/ingress.yaml b/sentrius-gcp-chart/templates/ingress.yaml index aa2d2578..247fdc6a 100644 --- a/sentrius-gcp-chart/templates/ingress.yaml +++ b/sentrius-gcp-chart/templates/ingress.yaml @@ -1,16 +1,13 @@ apiVersion: networking.k8s.io/v1 kind: Ingress metadata: - name: ingress-{{ .Values.tenant }} - namespace: {{ .Release.Namespace }} + name: managed-cert-ingress-canary + namespace: canary annotations: - kubernetes.io/ingress.class: "gce" + kubernetes.io/ingress.class: gce + kubernetes.io/ingress.allow-http: "false" + networking.gke.io/managed-certificates: wildcard-cert spec: - tls: - - hosts: - - {{ .Values.tenant }}.sentrius.cloud - - keycloak.{{ .Values.tenant }}.sentrius.cloud - secretName: {{ .Values.tenant }}-tls rules: - host: keycloak.{{ .Values.tenant }}.sentrius.cloud http: @@ -19,7 +16,7 @@ spec: pathType: Prefix backend: service: - name: sentrius-keycloak + name: {{ .Release.Name }}-keycloak port: number: 8081 - host: {{ .Values.tenant }}.sentrius.cloud @@ -29,6 +26,6 @@ spec: pathType: Prefix backend: service: - name: sentrius + name: {{ .Release.Name }}-sentrius port: number: 8080 diff --git a/sentrius-gcp-chart/templates/keycloak-service.yaml b/sentrius-gcp-chart/templates/keycloak-service.yaml index f74362e9..7e178a1e 100644 --- a/sentrius-gcp-chart/templates/keycloak-service.yaml +++ b/sentrius-gcp-chart/templates/keycloak-service.yaml @@ -6,10 +6,10 @@ metadata: app: keycloak release: {{ .Release.Name }} spec: - type: LoadBalancer + type: ClusterIP ports: - name: http - port: 80 + port: {{ .Values.keycloak.port }} targetPort: {{ .Values.keycloak.port }} # Replace with the internal port Keycloak listens to selector: app: keycloak diff --git a/sentrius-gcp-chart/templates/managed-cert.yaml b/sentrius-gcp-chart/templates/managed-cert.yaml new file mode 100644 index 00000000..aff201a0 --- /dev/null +++ b/sentrius-gcp-chart/templates/managed-cert.yaml @@ -0,0 +1,8 @@ +apiVersion: networking.gke.io/v1 +kind: ManagedCertificate +metadata: + name: wildcard-cert +spec: + domains: + - "{{ .Values.tenant }}.sentrius.cloud" + - "keycloak.{{ .Values.tenant }}.sentrius.cloud" diff --git a/sentrius-gcp-chart/templates/managed-certificate.yaml b/sentrius-gcp-chart/templates/managed-certificate.yaml deleted file mode 100644 index a7c33b59..00000000 --- a/sentrius-gcp-chart/templates/managed-certificate.yaml +++ /dev/null @@ -1,9 +0,0 @@ -apiVersion: networking.gke.io/v1 -kind: ManagedCertificate -metadata: - name: keycloak-cert - namespace: {{ .Values.tenant }} -spec: - domains: - - {{ .Values.subdomain }} - - keycloak.{{ .Values.subdomain }} diff --git a/sentrius-gcp-chart/templates/service.yaml b/sentrius-gcp-chart/templates/service.yaml index 0a76aa23..58a177f3 100644 --- a/sentrius-gcp-chart/templates/service.yaml +++ b/sentrius-gcp-chart/templates/service.yaml @@ -5,10 +5,10 @@ metadata: labels: app: sentrius spec: - type: LoadBalancer + type: ClusterIP ports: - name: http - port: 80 + port: {{ .Values.sentrius.port }} targetPort: {{ .Values.sentrius.port }} # Port used inside the container selector: app: sentrius \ No newline at end of file From 485d874646a8d52737b81f53d6bc74f9f8479c2d Mon Sep 17 00:00:00 2001 From: Marc Parisi Date: Mon, 6 Jan 2025 16:44:04 -0500 Subject: [PATCH 06/11] updates --- .gcp.env | 4 ++-- analyagents/pom.xml | 5 +++++ api/pom.xml | 5 +++++ docker/keycloak/Dockerfile | 2 +- sentrius-gcp-chart/templates/configmap.yaml | 2 ++ sentrius-gcp-chart/templates/keycloak-deployment.yaml | 2 +- 6 files changed, 16 insertions(+), 4 deletions(-) diff --git a/.gcp.env b/.gcp.env index d4c2f87c..7f3d5d74 100644 --- a/.gcp.env +++ b/.gcp.env @@ -1,4 +1,4 @@ -SENTRIUS_VERSION=1.0.10 +SENTRIUS_VERSION=1.0.11 SENTRIUS_SSH_VERSION=1.0.2 -SENTRIUS_KEYCLOAK_VERSION=1.0.3 +SENTRIUS_KEYCLOAK_VERSION=1.0.4 SENTRIUS_AGENT_VERSION=1.0.11 \ No newline at end of file diff --git a/analyagents/pom.xml b/analyagents/pom.xml index 004f916c..45e31471 100644 --- a/analyagents/pom.xml +++ b/analyagents/pom.xml @@ -48,6 +48,11 @@ junit-jupiter-params test + + + org.springframework.boot + spring-boot-starter-actuator + org.postgresql postgresql diff --git a/api/pom.xml b/api/pom.xml index 7a3388bf..7c6cba91 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -63,6 +63,11 @@ ${spring.boot.version} + + org.springframework.boot + spring-boot-starter-actuator + + org.springframework.boot spring-boot-devtools diff --git a/docker/keycloak/Dockerfile b/docker/keycloak/Dockerfile index 6d3e1949..11eae5da 100644 --- a/docker/keycloak/Dockerfile +++ b/docker/keycloak/Dockerfile @@ -19,5 +19,5 @@ COPY ./realms/sentrius-realm.json /opt/keycloak/data/import/sentrius-realm.json RUN ls -l /opt/keycloak/data/import/sentrius-realm.json ENTRYPOINT ["/opt/keycloak/bin/kc.sh"] -CMD ["start-dev", "--proxy=passthrough", "--import-realm"] +CMD ["start-dev", "--proxy=passthrough", "--import-realm", "--health-enabled=true"] diff --git a/sentrius-gcp-chart/templates/configmap.yaml b/sentrius-gcp-chart/templates/configmap.yaml index 9e6231dd..5014f199 100644 --- a/sentrius-gcp-chart/templates/configmap.yaml +++ b/sentrius-gcp-chart/templates/configmap.yaml @@ -96,6 +96,8 @@ data: server.error.whitelabel.enabled=false dynamic.properties.path=/config/dynamic.properties keycloak.realm=sentrius + management.endpoints.web.exposure.include=health + management.endpoint.health.show-details=always # Keycloak configuration spring.security.oauth2.client.registration.keycloak.client-id={{ .Values.sentrius.oauth2.client_id }} spring.security.oauth2.client.registration.keycloak.client-secret={{ .Values.sentrius.oauth2.client_secret }} diff --git a/sentrius-gcp-chart/templates/keycloak-deployment.yaml b/sentrius-gcp-chart/templates/keycloak-deployment.yaml index 57231199..eec66375 100644 --- a/sentrius-gcp-chart/templates/keycloak-deployment.yaml +++ b/sentrius-gcp-chart/templates/keycloak-deployment.yaml @@ -59,4 +59,4 @@ spec: - name: KC_HTTP_ENABLED value: "true" command: [ "/opt/keycloak/bin/kc.sh" ] - args: [ "start-dev", "--proxy=edge", "--import-realm"] + args: [ "start-dev", "--proxy=edge", "--import-realm", "--health-enabled=true"] From 98313eea939a2a698477a84561882a22a78c52fa Mon Sep 17 00:00:00 2001 From: Marc Parisi Date: Tue, 7 Jan 2025 05:39:02 -0500 Subject: [PATCH 07/11] allow actuator health --- analyagents/pom.xml | 1 + analyagents/src/main/resources/application.properties | 4 +++- api/pom.xml | 1 + api/src/main/java/io/sentrius/sso/config/SecurityConfig.java | 5 ++++- api/src/main/resources/application.properties | 5 ++++- pom.xml | 4 ---- 6 files changed, 13 insertions(+), 7 deletions(-) diff --git a/analyagents/pom.xml b/analyagents/pom.xml index 45e31471..dee6c11c 100644 --- a/analyagents/pom.xml +++ b/analyagents/pom.xml @@ -52,6 +52,7 @@ org.springframework.boot spring-boot-starter-actuator + ${spring.boot.version} org.postgresql diff --git a/analyagents/src/main/resources/application.properties b/analyagents/src/main/resources/application.properties index eb3438e2..af5a66b9 100644 --- a/analyagents/src/main/resources/application.properties +++ b/analyagents/src/main/resources/application.properties @@ -59,4 +59,6 @@ spring.security.oauth2.client.registration.keycloak.scope=openid,profile,email spring.security.oauth2.resourceserver.jwt.issuer-uri=http://192.168.1.162:8180/realms/sentrius spring.security.oauth2.client.provider.keycloak.issuer-uri=http://192.168.1.162:8180/realms/sentrius # for testing analytics agents -agents.session-analytics.enabled=true \ No newline at end of file +agents.session-analytics.enabled=true +management.endpoints.web.exposure.include=health +management.endpoint.health.show-details=always \ No newline at end of file diff --git a/api/pom.xml b/api/pom.xml index 7c6cba91..0d099656 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -66,6 +66,7 @@ org.springframework.boot spring-boot-starter-actuator + ${spring.boot.version} diff --git a/api/src/main/java/io/sentrius/sso/config/SecurityConfig.java b/api/src/main/java/io/sentrius/sso/config/SecurityConfig.java index 3a7eaa23..15386a95 100644 --- a/api/src/main/java/io/sentrius/sso/config/SecurityConfig.java +++ b/api/src/main/java/io/sentrius/sso/config/SecurityConfig.java @@ -91,7 +91,10 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti .exceptionHandling(exception -> exception .accessDeniedPage("/error") );*/ - http.authorizeHttpRequests(auth -> auth.requestMatchers("/**").fullyAuthenticated()) + http + .authorizeHttpRequests(auth -> auth. + requestMatchers("/actuator/**").permitAll() // Public endpoints + .requestMatchers("/**").fullyAuthenticated()) .oauth2ResourceServer(oauth2 -> oauth2 .jwt(jwt -> jwt.jwtAuthenticationConverter(jwtAuthenticationConverterForKeycloak())) ) diff --git a/api/src/main/resources/application.properties b/api/src/main/resources/application.properties index bdbf2c96..b90ec691 100644 --- a/api/src/main/resources/application.properties +++ b/api/src/main/resources/application.properties @@ -72,4 +72,7 @@ spring.security.oauth2.client.registration.keycloak.redirect-uri=http://192.168. spring.security.oauth2.client.registration.keycloak.scope=openid,profile,email spring.security.oauth2.resourceserver.jwt.issuer-uri=http://192.168.1.162:8180/realms/sentrius -spring.security.oauth2.client.provider.keycloak.issuer-uri=http://192.168.1.162:8180/realms/sentrius \ No newline at end of file +spring.security.oauth2.client.provider.keycloak.issuer-uri=http://192.168.1.162:8180/realms/sentrius + +management.endpoints.web.exposure.include=health +management.endpoint.health.show-details=always \ No newline at end of file diff --git a/pom.xml b/pom.xml index 8c8d378a..563cb958 100644 --- a/pom.xml +++ b/pom.xml @@ -94,10 +94,6 @@ spring-boot-devtools true - - org.springframework.boot - spring-boot-starter-actuator - io.hypersistence hypersistence-utils-hibernate-60 From c339153615562dbe24a7b51f002d7652ac2eeadc Mon Sep 17 00:00:00 2001 From: Marc Parisi Date: Tue, 7 Jan 2025 07:25:45 -0500 Subject: [PATCH 08/11] better deployment --- .gcp.env | 2 +- ops-scripts/gcp/depoloy-helm.sh | 6 +++--- sentrius-gcp-chart/templates/configmap.yaml | 12 ++++++------ sentrius-gcp-chart/templates/ingress.yaml | 4 ++-- .../templates/keycloak-healthcheck.yaml | 13 +++++++++++++ sentrius-gcp-chart/templates/keycloak-service.yaml | 4 ++++ .../templates/sentrius-healthcheck.yaml | 13 +++++++++++++ sentrius-gcp-chart/templates/service.yaml | 3 +++ 8 files changed, 45 insertions(+), 12 deletions(-) create mode 100644 sentrius-gcp-chart/templates/keycloak-healthcheck.yaml create mode 100644 sentrius-gcp-chart/templates/sentrius-healthcheck.yaml diff --git a/.gcp.env b/.gcp.env index 7f3d5d74..ef5232d5 100644 --- a/.gcp.env +++ b/.gcp.env @@ -1,4 +1,4 @@ -SENTRIUS_VERSION=1.0.11 +SENTRIUS_VERSION=1.0.12 SENTRIUS_SSH_VERSION=1.0.2 SENTRIUS_KEYCLOAK_VERSION=1.0.4 SENTRIUS_AGENT_VERSION=1.0.11 \ No newline at end of file diff --git a/ops-scripts/gcp/depoloy-helm.sh b/ops-scripts/gcp/depoloy-helm.sh index f5de5720..e607a107 100755 --- a/ops-scripts/gcp/depoloy-helm.sh +++ b/ops-scripts/gcp/depoloy-helm.sh @@ -46,7 +46,7 @@ for ((i=1; i<=RETRIES; i++)); do INGRESS_IP=$(kubectl get ingress managed-cert-ingress-${TENANT} -n ${TENANT} -o jsonpath='{.status.loadBalancer.ingress[0].ip}') - if [[ -n "INGRESS_IP" ]]; then + if [[ -n "$INGRESS_IP" ]]; then echo "INGRESS_IP IP: $INGRESS_IP" break fi @@ -55,7 +55,7 @@ for ((i=1; i<=RETRIES; i++)); do sleep $SLEEP_INTERVAL done -if [[ -z "INGRESS_IP" ]]; then +if [[ -z "$INGRESS_IP" ]]; then echo "Failed to retrieve LoadBalancer IPs after $((RETRIES * SLEEP_INTERVAL)) seconds." exit 1 fi @@ -71,7 +71,7 @@ else --name=${TENANT}.sentrius.cloud. \ --type=A \ --ttl=300 \ - $NGRESS_IP + $INGRESS_IP gcloud dns record-sets transaction add --zone=${ZONE} \ --name=keycloak.${TENANT}.sentrius.cloud. \ diff --git a/sentrius-gcp-chart/templates/configmap.yaml b/sentrius-gcp-chart/templates/configmap.yaml index 5014f199..a714d991 100644 --- a/sentrius-gcp-chart/templates/configmap.yaml +++ b/sentrius-gcp-chart/templates/configmap.yaml @@ -50,10 +50,10 @@ data: spring.security.oauth2.client.registration.keycloak.client-id="{{ .Values.sentrius.oauth2.client_id }}" spring.security.oauth2.client.registration.keycloak.client-secret="{{ .Values.sentrius.oauth2.client_secret }}" spring.security.oauth2.client.registration.keycloak.authorization-grant-type="{{ .Values.sentrius.oauth2.authorization_grant_type }}" - spring.security.oauth2.client.registration.keycloak.redirect-uri=http://{{ .Values.subdomain }}/login/oauth2/code/keycloak + spring.security.oauth2.client.registration.keycloak.redirect-uri=https://{{ .Values.subdomain }}/login/oauth2/code/keycloak spring.security.oauth2.client.registration.keycloak.scope="{{ .Values.sentrius.oauth2.scope }}" - spring.security.oauth2.resourceserver.jwt.issuer-uri=http://keycloak.{{ .Values.subdomain }}/realms/sentrius - spring.security.oauth2.client.provider.keycloak.issuer-uri=http://keycloak.{{ .Values.tenant }}.sentrius.cloud/realms/sentrius + spring.security.oauth2.resourceserver.jwt.issuer-uri=https://keycloak.{{ .Values.subdomain }}/realms/sentrius + spring.security.oauth2.client.provider.keycloak.issuer-uri=https://keycloak.{{ .Values.tenant }}.sentrius.cloud/realms/sentrius agents.session-analytics.enabled=true api-application.properties: | keystore.file=sso.jceks @@ -102,10 +102,10 @@ data: spring.security.oauth2.client.registration.keycloak.client-id={{ .Values.sentrius.oauth2.client_id }} spring.security.oauth2.client.registration.keycloak.client-secret={{ .Values.sentrius.oauth2.client_secret }} spring.security.oauth2.client.registration.keycloak.authorization-grant-type={{ .Values.sentrius.oauth2.authorization_grant_type }} - spring.security.oauth2.client.registration.keycloak.redirect-uri=http://{{ .Values.subdomain }}/login/oauth2/code/keycloak + spring.security.oauth2.client.registration.keycloak.redirect-uri=https://{{ .Values.subdomain }}/login/oauth2/code/keycloak spring.security.oauth2.client.registration.keycloak.scope={{ .Values.sentrius.oauth2.scope }} - spring.security.oauth2.resourceserver.jwt.issuer-uri=http://keycloak.{{ .Values.subdomain }}/realms/sentrius - spring.security.oauth2.client.provider.keycloak.issuer-uri=http://keycloak.{{ .Values.tenant }}.sentrius.cloud/realms/sentrius + spring.security.oauth2.resourceserver.jwt.issuer-uri=https://keycloak.{{ .Values.subdomain }}/realms/sentrius + spring.security.oauth2.client.provider.keycloak.issuer-uri=https://keycloak.{{ .Values.tenant }}.sentrius.cloud/realms/sentrius dynamic.properties: | auditorClass=io.sentrius.sso.automation.auditing.AccessTokenAuditor twopartyapproval.option.LOCKING_SYSTEMS=true diff --git a/sentrius-gcp-chart/templates/ingress.yaml b/sentrius-gcp-chart/templates/ingress.yaml index 247fdc6a..7e0c002d 100644 --- a/sentrius-gcp-chart/templates/ingress.yaml +++ b/sentrius-gcp-chart/templates/ingress.yaml @@ -1,8 +1,8 @@ apiVersion: networking.k8s.io/v1 kind: Ingress metadata: - name: managed-cert-ingress-canary - namespace: canary + name: managed-cert-ingress-{{ .Values.tenant }} + namespace: {{ .Values.tenant }} annotations: kubernetes.io/ingress.class: gce kubernetes.io/ingress.allow-http: "false" diff --git a/sentrius-gcp-chart/templates/keycloak-healthcheck.yaml b/sentrius-gcp-chart/templates/keycloak-healthcheck.yaml new file mode 100644 index 00000000..77649f46 --- /dev/null +++ b/sentrius-gcp-chart/templates/keycloak-healthcheck.yaml @@ -0,0 +1,13 @@ +apiVersion: cloud.google.com/v1 +kind: BackendConfig +metadata: + name: keycloak-backend-config + namespace: {{ .Values.tenant }} +spec: + healthCheck: + checkIntervalSec: 10 + timeoutSec: 5 + healthyThreshold: 2 + unhealthyThreshold: 2 + requestPath: /health/ready + port: 8081 diff --git a/sentrius-gcp-chart/templates/keycloak-service.yaml b/sentrius-gcp-chart/templates/keycloak-service.yaml index 7e178a1e..04d2e5bc 100644 --- a/sentrius-gcp-chart/templates/keycloak-service.yaml +++ b/sentrius-gcp-chart/templates/keycloak-service.yaml @@ -2,9 +2,13 @@ apiVersion: v1 kind: Service metadata: name: {{ .Release.Name }}-keycloak + namespace: {{ .Values.tenant }} + annotations: + cloud.google.com/backend-config: '{"default": "keycloak-backend-config"}' labels: app: keycloak release: {{ .Release.Name }} + spec: type: ClusterIP ports: diff --git a/sentrius-gcp-chart/templates/sentrius-healthcheck.yaml b/sentrius-gcp-chart/templates/sentrius-healthcheck.yaml new file mode 100644 index 00000000..745978a7 --- /dev/null +++ b/sentrius-gcp-chart/templates/sentrius-healthcheck.yaml @@ -0,0 +1,13 @@ +apiVersion: cloud.google.com/v1 +kind: BackendConfig +metadata: + name: sentrius-backend-config + namespace: {{ .Values.tenant }} +spec: + healthCheck: + checkIntervalSec: 10 + timeoutSec: 5 + healthyThreshold: 2 + unhealthyThreshold: 2 + requestPath: /actuator/health + port: 8080 diff --git a/sentrius-gcp-chart/templates/service.yaml b/sentrius-gcp-chart/templates/service.yaml index 58a177f3..04a7add3 100644 --- a/sentrius-gcp-chart/templates/service.yaml +++ b/sentrius-gcp-chart/templates/service.yaml @@ -2,6 +2,9 @@ apiVersion: v1 kind: Service metadata: name: {{ .Release.Name }}-sentrius + namespace: {{ .Values.tenant }} + annotations: + cloud.google.com/backend-config: '{"default": "sentrius-backend-config"}' labels: app: sentrius spec: From 6f7692460d11ec8991a68951d05a777eb0b6a4a6 Mon Sep 17 00:00:00 2001 From: Marc Parisi Date: Tue, 7 Jan 2025 09:09:07 -0500 Subject: [PATCH 09/11] minor fixes --- .gcp.env | 2 +- api/pom.xml | 5 ++ .../sso/config/HttpsRedirectConfig.java | 29 ++++++++++ .../sentrius/sso/config/SecurityConfig.java | 55 ------------------- pom.xml | 5 ++ sentrius-gcp-chart/templates/configmap.yaml | 2 + sentrius-gcp-chart/templates/ingress.yaml | 2 + 7 files changed, 44 insertions(+), 56 deletions(-) create mode 100644 api/src/main/java/io/sentrius/sso/config/HttpsRedirectConfig.java diff --git a/.gcp.env b/.gcp.env index ef5232d5..5b93bd51 100644 --- a/.gcp.env +++ b/.gcp.env @@ -1,4 +1,4 @@ -SENTRIUS_VERSION=1.0.12 +SENTRIUS_VERSION=1.0.13 SENTRIUS_SSH_VERSION=1.0.2 SENTRIUS_KEYCLOAK_VERSION=1.0.4 SENTRIUS_AGENT_VERSION=1.0.11 \ No newline at end of file diff --git a/api/pom.xml b/api/pom.xml index 0d099656..421e153c 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -68,6 +68,11 @@ spring-boot-starter-actuator ${spring.boot.version} + + org.springframework.boot + spring-boot-starter-webflux + ${spring.boot.version} + org.springframework.boot diff --git a/api/src/main/java/io/sentrius/sso/config/HttpsRedirectConfig.java b/api/src/main/java/io/sentrius/sso/config/HttpsRedirectConfig.java new file mode 100644 index 00000000..4ffb391d --- /dev/null +++ b/api/src/main/java/io/sentrius/sso/config/HttpsRedirectConfig.java @@ -0,0 +1,29 @@ +package io.sentrius.sso.config; + +import java.net.URI; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.server.WebFilter; + +@Configuration +public class HttpsRedirectConfig { + + @Value("${https.redirect.enabled:true}") // Default is true + private boolean httpsRedirectEnabled; + + @Bean + public WebFilter httpsRedirectFilter() { + return (exchange, chain) -> { + if (httpsRedirectEnabled && + exchange.getRequest().getHeaders().containsKey("X-Forwarded-Proto") && + "http".equals(exchange.getRequest().getHeaders().getFirst("X-Forwarded-Proto"))) { + URI httpsUri = exchange.getRequest() + .getURI() + .resolve(exchange.getRequest().getURI().toString().replace("http://", "https://")); + return exchange.getResponse().setComplete(); + } + return chain.filter(exchange); + }; + } +} \ No newline at end of file diff --git a/api/src/main/java/io/sentrius/sso/config/SecurityConfig.java b/api/src/main/java/io/sentrius/sso/config/SecurityConfig.java index 15386a95..fe6591c9 100644 --- a/api/src/main/java/io/sentrius/sso/config/SecurityConfig.java +++ b/api/src/main/java/io/sentrius/sso/config/SecurityConfig.java @@ -42,55 +42,6 @@ public class SecurityConfig { @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { - /* http - .authorizeRequests(authorize -> authorize - .requestMatchers("/sso/v1/**", "/api/v1/**").authenticated() // Pages that need authentication - .requestMatchers("/node/**", "/js/**", "/css/**", "/images/**", "/error", "/sso/login", "/api/v1/login/authenticate").permitAll() // Public endpoints - .anyRequest().authenticated() // Other pages need authentication - ) - .logout(logout -> logout - .logoutSuccessUrl("/sso/login?logout") // Redirect after logout - ) - .sessionManagement(session -> session - .sessionCreationPolicy(SessionCreationPolicy.STATELESS) - ) - .oauth2Login(oauth2 -> oauth2 // Enable OAuth2 login - .loginPage("/oauth2/authorization/keycloak") // Redirect to Keycloak - ) - .oauth2ResourceServer(oauth2 -> oauth2 - .jwt(jwt -> jwt.jwtAuthenticationConverter(jwtAuthenticationConverterForKeycloak())) - ) - .csrf(csrf -> csrf - .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()) - ) - - .cors(Customizer.withDefaults()) - .exceptionHandling(exception -> exception - .accessDeniedPage("/error") // Handle access denied with error page - );*/ - /* - http - .authorizeRequests(authorize -> authorize - .requestMatchers("/sso/v1/**", "/api/v1/**").authenticated() - .requestMatchers("/node/**", "/js/**", "/css/**", "/images/**", "/error", "/sso/login", "/api/v1/login/authenticate").permitAll() - .anyRequest().authenticated() - ) - .sessionManagement(session -> session - .sessionCreationPolicy(SessionCreationPolicy.STATELESS) - ) - .oauth2Login(oauth2 -> oauth2 - .loginPage("/oauth2/authorization/keycloak") - ) - .oauth2ResourceServer(oauth2 -> oauth2 - .jwt(jwt -> jwt.jwtAuthenticationConverter(jwtAuthenticationConverterForKeycloak())) - ) - .csrf(csrf -> csrf - .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()) - ) - .cors(Customizer.withDefaults()) - .exceptionHandling(exception -> exception - .accessDeniedPage("/error") - );*/ http .authorizeHttpRequests(auth -> auth. requestMatchers("/actuator/**").permitAll() // Public endpoints @@ -107,12 +58,6 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti return http.build(); } - /* - @Bean - public JwtDecoder jwtDecoder(OAuth2ResourceServerProperties properties) { - return JwtDecoders.fromIssuerLocation("http://localhost:8180/realms/sentrius"); - } -*/ @Bean public JwtAuthenticationConverter jwtAuthenticationConverterForKeycloak() { JwtAuthenticationConverter converter = new JwtAuthenticationConverter(); diff --git a/pom.xml b/pom.xml index 563cb958..8792f1ad 100644 --- a/pom.xml +++ b/pom.xml @@ -159,6 +159,11 @@ spring-boot-starter-actuator ${spring.boot.version} + + org.springframework.boot + spring-boot-starter-webflux + ${spring.boot.version} + org.springframework.boot spring-boot-starter-security diff --git a/sentrius-gcp-chart/templates/configmap.yaml b/sentrius-gcp-chart/templates/configmap.yaml index a714d991..5914a85b 100644 --- a/sentrius-gcp-chart/templates/configmap.yaml +++ b/sentrius-gcp-chart/templates/configmap.yaml @@ -106,6 +106,8 @@ data: spring.security.oauth2.client.registration.keycloak.scope={{ .Values.sentrius.oauth2.scope }} spring.security.oauth2.resourceserver.jwt.issuer-uri=https://keycloak.{{ .Values.subdomain }}/realms/sentrius spring.security.oauth2.client.provider.keycloak.issuer-uri=https://keycloak.{{ .Values.tenant }}.sentrius.cloud/realms/sentrius + server.forward-headers-strategy=native + https.redirect.enabled=true dynamic.properties: | auditorClass=io.sentrius.sso.automation.auditing.AccessTokenAuditor twopartyapproval.option.LOCKING_SYSTEMS=true diff --git a/sentrius-gcp-chart/templates/ingress.yaml b/sentrius-gcp-chart/templates/ingress.yaml index 7e0c002d..a89a55f9 100644 --- a/sentrius-gcp-chart/templates/ingress.yaml +++ b/sentrius-gcp-chart/templates/ingress.yaml @@ -6,6 +6,8 @@ metadata: annotations: kubernetes.io/ingress.class: gce kubernetes.io/ingress.allow-http: "false" + ingress.kubernetes.io/force-ssl-redirect: "true" + ingress.kubernetes.io/redirect-http-to-https: "true" networking.gke.io/managed-certificates: wildcard-cert spec: rules: From ed02fd0743ca316c9cda7967761055f125e4707b Mon Sep 17 00:00:00 2001 From: Marc Parisi Date: Tue, 7 Jan 2025 10:00:25 -0500 Subject: [PATCH 10/11] commit --- .gcp.env | 2 +- .../io/sentrius/sso/controllers/api/RuleApiController.java | 3 ++- .../sentrius/sso/startup/ConfigurationApplicationTask.java | 5 +++++ api/src/main/resources/templates/sso/errors/list_errors.html | 2 +- .../main/java/io/sentrius/sso/core/services/RuleService.java | 4 +++- docker/keycloak/realms/sentrius-realm.json | 2 +- sentrius-gcp-chart/templates/keycloak-deployment.yaml | 4 ++-- 7 files changed, 15 insertions(+), 7 deletions(-) diff --git a/.gcp.env b/.gcp.env index 5b93bd51..920b01fd 100644 --- a/.gcp.env +++ b/.gcp.env @@ -1,4 +1,4 @@ -SENTRIUS_VERSION=1.0.13 +SENTRIUS_VERSION=1.0.15 SENTRIUS_SSH_VERSION=1.0.2 SENTRIUS_KEYCLOAK_VERSION=1.0.4 SENTRIUS_AGENT_VERSION=1.0.11 \ No newline at end of file diff --git a/api/src/main/java/io/sentrius/sso/controllers/api/RuleApiController.java b/api/src/main/java/io/sentrius/sso/controllers/api/RuleApiController.java index 08020db5..4015a222 100644 --- a/api/src/main/java/io/sentrius/sso/controllers/api/RuleApiController.java +++ b/api/src/main/java/io/sentrius/sso/controllers/api/RuleApiController.java @@ -77,7 +77,7 @@ public ResponseEntity> listRules(HttpServletRequest request boolean canEditRules = AccessUtil.canAccess(user, RuleAccessEnum.CAN_EDIT_RULES); boolean canDeleteRules = AccessUtil.canAccess(user, RuleAccessEnum.CAN_MANAGE_RULES); if (AccessUtil.canAccess(user, ApplicationAccessEnum.CAN_MANAGE_APPLICATION)) { - + log.info("User can manage rules {}", user.getAuthorizationType()); for(ProfileRule rule: ruleService.getAllRules()) { var dto = new ProfileRuleDTO(rule, rule.getHostGroups().stream().toList(), canViewRules, canEditRules, canDeleteRules); @@ -85,6 +85,7 @@ public ResponseEntity> listRules(HttpServletRequest request log.info("Adding {}", dto); } } else { + log.info("User can manage own rules"); var groups = hostGroupService.getAllHostGroups(user); for (HostGroup group : groups) { for(ProfileRule rule : group.getRules()) { diff --git a/api/src/main/java/io/sentrius/sso/startup/ConfigurationApplicationTask.java b/api/src/main/java/io/sentrius/sso/startup/ConfigurationApplicationTask.java index ce991517..8b68fafd 100644 --- a/api/src/main/java/io/sentrius/sso/startup/ConfigurationApplicationTask.java +++ b/api/src/main/java/io/sentrius/sso/startup/ConfigurationApplicationTask.java @@ -29,6 +29,7 @@ import io.sentrius.sso.core.model.dto.UserTypeDTO; import io.sentrius.sso.core.model.hostgroup.HostGroup; import io.sentrius.sso.core.model.security.UserType; +import io.sentrius.sso.core.model.security.enums.ApplicationAccessEnum; import io.sentrius.sso.core.model.security.enums.AutomationAccessEnum; import io.sentrius.sso.core.model.security.enums.RuleAccessEnum; import io.sentrius.sso.core.model.security.enums.SSHAccessEnum; @@ -337,6 +338,10 @@ protected List createUserTypes(List sideEffects, InstallCo builder.ztAccessTokenAccess(ZeroTrustAccessTokenEnum.of(List.of(type.getZtAccessTokenAccess()))); } + if (null != type.getApplicationAccess()){ + builder.applicationAccess(ApplicationAccessEnum.of(List.of(type.getApplicationAccess()))); + } + UserType newType = builder.userTypeName(type.getUserTypeName()).build(); userTypeRepository.findByUserTypeName(type.getUserTypeName()) .ifPresentOrElse( diff --git a/api/src/main/resources/templates/sso/errors/list_errors.html b/api/src/main/resources/templates/sso/errors/list_errors.html index 34fa7b39..21f593e2 100755 --- a/api/src/main/resources/templates/sso/errors/list_errors.html +++ b/api/src/main/resources/templates/sso/errors/list_errors.html @@ -111,7 +111,7 @@
-
+

Errors

diff --git a/core/src/main/java/io/sentrius/sso/core/services/RuleService.java b/core/src/main/java/io/sentrius/sso/core/services/RuleService.java index 9c5c5f4f..ceb44e74 100644 --- a/core/src/main/java/io/sentrius/sso/core/services/RuleService.java +++ b/core/src/main/java/io/sentrius/sso/core/services/RuleService.java @@ -32,7 +32,9 @@ public void deleteRule(ProfileRule rule) { public ProfileRule saveRule(ProfileRule rule) { try { log.info("Saving rule with id: {}", rule.getId()); - return ruleRepository.save(rule); + var newRule = ruleRepository.save(rule); + log.info("Saving rule with id: {}", newRule.getId()); + return newRule; } catch (Exception e) { log.error("Error while saving Rule", e); throw new RuntimeException("Failed to save Rule", e); diff --git a/docker/keycloak/realms/sentrius-realm.json b/docker/keycloak/realms/sentrius-realm.json index d257796e..32164353 100644 --- a/docker/keycloak/realms/sentrius-realm.json +++ b/docker/keycloak/realms/sentrius-realm.json @@ -8,7 +8,7 @@ "clientAuthenticatorType": "client-secret", "secret": "nGkEukexSWTvDzYjSkDmeUlM0FJ5Jhh0", "rootUrl": "${ROOT_URL}", - "baseUrl": "/", + "baseUrl": "${ROOT_URL}", "redirectUris": ["${REDIRECT_URIS}/*"], "protocol": "openid-connect" } diff --git a/sentrius-gcp-chart/templates/keycloak-deployment.yaml b/sentrius-gcp-chart/templates/keycloak-deployment.yaml index eec66375..d2b76ee9 100644 --- a/sentrius-gcp-chart/templates/keycloak-deployment.yaml +++ b/sentrius-gcp-chart/templates/keycloak-deployment.yaml @@ -49,9 +49,9 @@ spec: - name: ROOT_LOGLEVEL value: DEBUG - name: ROOT_URL - value: http://{{ .Values.subdomain }}/ + value: https://{{ .Values.subdomain }}/ - name: REDIRECT_URIS - value: http://{{ .Values.subdomain }} + value: https://{{ .Values.subdomain }} - name: PROXY_ADDRESS_FORWARDING value: "true" - name: KC_HOSTNAME_STRICT_HTTPS From 0bbc2e740891474d1848c71d417139ca3ad37038 Mon Sep 17 00:00:00 2001 From: Marc Parisi Date: Tue, 7 Jan 2025 11:37:36 -0500 Subject: [PATCH 11/11] commit --- .../gcp/{depoloy-helm.sh => deploy-helm.sh} | 0 ops-scripts/gcp/destroy-tenant.sh | 63 +++++++++++++++++++ 2 files changed, 63 insertions(+) rename ops-scripts/gcp/{depoloy-helm.sh => deploy-helm.sh} (100%) create mode 100755 ops-scripts/gcp/destroy-tenant.sh diff --git a/ops-scripts/gcp/depoloy-helm.sh b/ops-scripts/gcp/deploy-helm.sh similarity index 100% rename from ops-scripts/gcp/depoloy-helm.sh rename to ops-scripts/gcp/deploy-helm.sh diff --git a/ops-scripts/gcp/destroy-tenant.sh b/ops-scripts/gcp/destroy-tenant.sh new file mode 100755 index 00000000..35e4c07f --- /dev/null +++ b/ops-scripts/gcp/destroy-tenant.sh @@ -0,0 +1,63 @@ +#!/bin/bash + +SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) + +source ${SCRIPT_DIR}/base.sh +source ${SCRIPT_DIR}/../../.gcp.env + +TENANT=$1 + +if [[ -z "$TENANT" ]]; then + echo "Must provide single argument for tenant name" 1>&2 + exit 1 +fi + +# Check if namespace exists +kubectl get namespace ${TENANT} >/dev/null 2>&1 +if [[ $? -ne 0 ]]; then + echo "Namespace ${TENANT} does not exist. Nothing to delete." +else + echo "Deleting Kubernetes namespace ${TENANT}..." + kubectl delete namespace ${TENANT} --wait || echo "Failed to delete namespace ${TENANT}" +fi + +# Uninstall Helm release +echo "Uninstalling Helm release for tenant ${TENANT}..." +helm uninstall sentrius --namespace ${TENANT} || echo "Helm release not found for tenant ${TENANT}" + +# Delete DNS records +echo "Deleting DNS records for tenant ${TENANT}..." +gcloud dns record-sets transaction start --zone=${ZONE} + +# Retrieve DNS record details +TENANT_RECORD=$(gcloud dns record-sets list --zone=${ZONE} --name=${TENANT}.sentrius.cloud. --format="value(rrdatas[0],ttl,type)") +KEYCLOAK_RECORD=$(gcloud dns record-sets list --zone=${ZONE} --name=keycloak.${TENANT}.sentrius.cloud. --format="value(rrdatas[0],ttl,type)") + +# Delete tenant DNS record +if [[ -n "$TENANT_RECORD" ]]; then + read -r TENANT_RRDATA TENANT_TTL TENANT_TYPE <<< "$TENANT_RECORD" + gcloud dns record-sets transaction remove --zone=${ZONE} \ + --name=${TENANT}.sentrius.cloud. \ + --type=$TENANT_TYPE \ + --ttl=$TENANT_TTL \ + $TENANT_RRDATA || echo "Failed to remove DNS record for ${TENANT}.sentrius.cloud" +else + echo "No DNS record found for ${TENANT}.sentrius.cloud" +fi + +# Delete Keycloak DNS record +if [[ -n "$KEYCLOAK_RECORD" ]]; then + read -r KEYCLOAK_RRDATA KEYCLOAK_TTL KEYCLOAK_TYPE <<< "$KEYCLOAK_RECORD" + gcloud dns record-sets transaction remove --zone=${ZONE} \ + --name=keycloak.${TENANT}.sentrius.cloud. \ + --type=$KEYCLOAK_TYPE \ + --ttl=$KEYCLOAK_TTL \ + $KEYCLOAK_RRDATA || echo "Failed to remove DNS record for keycloak.${TENANT}.sentrius.cloud" +else + echo "No DNS record found for keycloak.${TENANT}.sentrius.cloud" +fi + +# Execute the DNS record transaction +gcloud dns record-sets transaction execute --zone=${ZONE} || echo "No DNS changes applied." + +echo "All resources for tenant ${TENANT} have been deleted."