From f1851215f88f0217ba77592e13c5472c907d6bde Mon Sep 17 00:00:00 2001 From: moauto <54212639+mo-auto@users.noreply.github.com> Date: Wed, 6 Nov 2024 23:04:02 +0000 Subject: [PATCH] Set stable to v5.1.5 --- charts/gluu-5.1.6-dev.tgz | Bin 100091 -> 100311 bytes charts/gluu-all-in-one-5.1.6-dev.tgz | Bin 31789 -> 31793 bytes charts/index.yaml | 110 +++++++++--------- .../admin/kubernetes-ops/upgrade/index.html | 2 +- .../getting-started-rancher/index.html | 2 +- .../docker-install/quick-start/index.html | 2 +- .../helm-install/amazon-eks/index.html | 2 +- .../helm-install/google-gke/index.html | 2 +- .../install/helm-install/local/index.html | 4 +- .../helm-install/microsoft-azure/index.html | 2 +- .../install/helm-install/rancher/index.html | 4 +- .../install/vm-install/rhel/index.html | 10 +- .../install/vm-install/suse/index.html | 10 +- .../install/vm-install/ubuntu/index.html | 18 +-- .../vm-install/vm-requirements/index.html | 2 +- v5.1.6.nightly/openbanking/index.html | 2 +- .../openbanking/install-cn/index.html | 4 +- .../openbanking/install-vm/index.html | 2 +- v5.1.6.nightly/search/search_index.json | 2 +- 19 files changed, 90 insertions(+), 90 deletions(-) diff --git a/charts/gluu-5.1.6-dev.tgz b/charts/gluu-5.1.6-dev.tgz index 88a705f44134230fdef3fc0ec7d3b3b0fb3dcce3..ea8bc5f15083d0eb0533a9007421fb4a42e32d9c 100644 GIT binary patch delta 97189 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를GoFWs$w9z6x})PIf?ZF=&E1)VKa_~f9D|iK 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 CS|mIG delta 97003 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 z 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�L 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 kc8a0PP;lA?2+lT=;*wx2N51 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

!1B% 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

+d@mBX6d$SIe? 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.21.0-0' @@ -139,7 +139,7 @@ entries: catalog.cattle.io/release-name: gluu apiVersion: v2 appVersion: 5.1.5 - created: "2024-11-05T23:03:52.141222778Z" + created: "2024-11-06T23:04:01.40922148Z" dependencies: - condition: global.config.enabled name: config @@ -248,7 +248,7 @@ entries: catalog.cattle.io/release-name: gluu apiVersion: v2 appVersion: 5.1.5-dev - created: "2024-11-05T23:03:52.130845516Z" + created: "2024-11-06T23:04:01.39908015Z" dependencies: - condition: global.config.enabled name: config @@ -357,7 +357,7 @@ entries: catalog.cattle.io/release-name: gluu apiVersion: v2 appVersion: 5.1.4 - created: "2024-11-05T23:03:52.120662276Z" + created: "2024-11-06T23:04:01.388901176Z" dependencies: - condition: global.config.enabled name: config @@ -466,7 +466,7 @@ entries: catalog.cattle.io/release-name: gluu apiVersion: v2 appVersion: 5.1.4-dev - created: "2024-11-05T23:03:52.110289736Z" + created: "2024-11-06T23:04:01.378445509Z" dependencies: - condition: global.config.enabled name: config @@ -575,7 +575,7 @@ entries: catalog.cattle.io/release-name: gluu apiVersion: v2 appVersion: 5.1.3 - created: "2024-11-05T23:03:52.09992747Z" + created: "2024-11-06T23:04:01.367994186Z" dependencies: - condition: global.config.enabled name: config @@ -684,7 +684,7 @@ entries: catalog.cattle.io/release-name: gluu apiVersion: v2 appVersion: 5.1.3-dev - created: "2024-11-05T23:03:52.089468987Z" + created: "2024-11-06T23:04:01.357534206Z" dependencies: - condition: global.config.enabled name: config @@ -793,7 +793,7 @@ entries: catalog.cattle.io/release-name: gluu apiVersion: v2 appVersion: 5.1.2 - created: "2024-11-05T23:03:52.079019322Z" + created: "2024-11-06T23:04:01.347048271Z" dependencies: - condition: global.config.enabled name: config @@ -902,7 +902,7 @@ entries: catalog.cattle.io/release-name: gluu apiVersion: v2 appVersion: 5.1.2 - created: "2024-11-05T23:03:52.068767233Z" + created: "2024-11-06T23:04:01.336695038Z" dependencies: - condition: global.config.enabled name: config @@ -1009,7 +1009,7 @@ entries: catalog.cattle.io/release-name: gluu apiVersion: v2 appVersion: 5.1.1 - created: "2024-11-05T23:03:52.058519195Z" + created: "2024-11-06T23:04:01.326451397Z" dependencies: - condition: global.config.enabled name: config @@ -1112,7 +1112,7 @@ entries: catalog.cattle.io/release-name: gluu apiVersion: v2 appVersion: 5.1.1 - created: "2024-11-05T23:03:52.048659038Z" + created: "2024-11-06T23:04:01.316636453Z" dependencies: - condition: global.config.enabled name: config @@ -1215,7 +1215,7 @@ entries: catalog.cattle.io/release-name: gluu apiVersion: v2 appVersion: 5.1.1 - created: "2024-11-05T23:03:52.038659839Z" + created: "2024-11-06T23:04:01.306612274Z" dependencies: - condition: global.config.enabled name: config @@ -1318,7 +1318,7 @@ entries: catalog.cattle.io/release-name: gluu apiVersion: v2 appVersion: 5.1.0 - created: "2024-11-05T23:03:52.028702643Z" + created: "2024-11-06T23:04:01.296556738Z" dependencies: - condition: global.config.enabled name: config @@ -1421,7 +1421,7 @@ entries: catalog.cattle.io/release-name: gluu apiVersion: v2 appVersion: 5.1.0 - created: "2024-11-05T23:03:52.018931299Z" + created: "2024-11-06T23:04:01.285869804Z" dependencies: - condition: global.config.enabled name: config @@ -1524,7 +1524,7 @@ entries: catalog.cattle.io/release-name: gluu apiVersion: v2 appVersion: 5.0.22 - created: "2024-11-05T23:03:52.009020831Z" + created: "2024-11-06T23:04:01.276315015Z" dependencies: - condition: global.config.enabled name: config @@ -1627,7 +1627,7 @@ entries: catalog.cattle.io/release-name: gluu apiVersion: v2 appVersion: 5.0.0 - created: "2024-11-05T23:03:51.99916536Z" + created: "2024-11-06T23:04:01.266757623Z" dependencies: - condition: global.config.enabled name: config @@ -1729,7 +1729,7 @@ entries: catalog.cattle.io/release-name: gluu apiVersion: v2 appVersion: 5.0.0 - created: "2024-11-05T23:03:51.988282941Z" + created: "2024-11-06T23:04:01.25730906Z" dependencies: - condition: global.config.enabled name: config @@ -1823,7 +1823,7 @@ entries: catalog.cattle.io/release-name: gluu apiVersion: v2 appVersion: 5.0.0 - created: "2024-11-05T23:03:51.980573858Z" + created: "2024-11-06T23:04:01.249086089Z" dependencies: - condition: global.config.enabled name: config @@ -1919,7 +1919,7 @@ entries: catalog.cattle.io/release-name: gluu apiVersion: v2 appVersion: 5.0.0 - created: "2024-11-05T23:03:51.971744301Z" + created: "2024-11-06T23:04:01.241085234Z" dependencies: - condition: global.config.enabled name: config @@ -2015,7 +2015,7 @@ entries: catalog.cattle.io/release-name: gluu apiVersion: v2 appVersion: 5.0.0 - created: "2024-11-05T23:03:51.962733807Z" + created: "2024-11-06T23:04:01.233422908Z" dependencies: - condition: global.config.enabled name: config @@ -2120,7 +2120,7 @@ entries: catalog.cattle.io/release-name: gluu apiVersion: v2 appVersion: 5.0.0 - created: "2024-11-05T23:03:51.953534809Z" + created: "2024-11-06T23:04:01.223640661Z" dependencies: - condition: global.config.enabled name: config @@ -2225,7 +2225,7 @@ entries: catalog.cattle.io/release-name: gluu apiVersion: v2 appVersion: 5.0.0 - created: "2024-11-05T23:03:51.945140393Z" + created: "2024-11-06T23:04:01.214350305Z" dependencies: - condition: global.config.enabled name: config @@ -2330,7 +2330,7 @@ entries: catalog.cattle.io/release-name: gluu apiVersion: v2 appVersion: 5.0.0 - created: "2024-11-05T23:03:51.93581204Z" + created: "2024-11-06T23:04:01.204966838Z" dependencies: - condition: global.config.enabled name: config @@ -2435,7 +2435,7 @@ entries: catalog.cattle.io/release-name: gluu apiVersion: v2 appVersion: 5.0.0 - created: "2024-11-05T23:03:51.926242416Z" + created: "2024-11-06T23:04:01.195656483Z" dependencies: - condition: global.config.enabled name: config @@ -2540,7 +2540,7 @@ entries: catalog.cattle.io/release-name: gluu apiVersion: v2 appVersion: 5.0.0 - created: "2024-11-05T23:03:51.917005024Z" + created: "2024-11-06T23:04:01.186509563Z" dependencies: - condition: global.config.enabled name: config @@ -2645,7 +2645,7 @@ entries: catalog.cattle.io/release-name: gluu apiVersion: v2 appVersion: 5.0.0 - created: "2024-11-05T23:03:51.907649361Z" + created: "2024-11-06T23:04:01.177326269Z" dependencies: - condition: global.config.enabled name: config @@ -2750,7 +2750,7 @@ entries: catalog.cattle.io/release-name: gluu apiVersion: v2 appVersion: 5.0.0 - created: "2024-11-05T23:03:51.898380359Z" + created: "2024-11-06T23:04:01.167522017Z" dependencies: - condition: global.config.enabled name: config @@ -2855,7 +2855,7 @@ entries: catalog.cattle.io/release-name: gluu apiVersion: v2 appVersion: 5.0.0 - created: "2024-11-05T23:03:51.888983462Z" + created: "2024-11-06T23:04:01.157696308Z" dependencies: - condition: global.config.enabled name: config @@ -2960,7 +2960,7 @@ entries: catalog.cattle.io/release-name: gluu apiVersion: v2 appVersion: 5.0.0 - created: "2024-11-05T23:03:51.87876408Z" + created: "2024-11-06T23:04:01.148676738Z" dependencies: - condition: global.config.enabled name: config @@ -3065,7 +3065,7 @@ entries: catalog.cattle.io/release-name: gluu apiVersion: v2 appVersion: 5.0.0 - created: "2024-11-05T23:03:51.870404429Z" + created: "2024-11-06T23:04:01.139767422Z" dependencies: - condition: global.config.enabled name: config @@ -3170,7 +3170,7 @@ entries: catalog.cattle.io/release-name: gluu apiVersion: v2 appVersion: 5.0.0 - created: "2024-11-05T23:03:51.86118653Z" + created: "2024-11-06T23:04:01.13083159Z" dependencies: - condition: global.config.enabled name: config @@ -3275,7 +3275,7 @@ entries: catalog.cattle.io/release-name: gluu apiVersion: v2 appVersion: 5.0.0 - created: "2024-11-05T23:03:51.851961506Z" + created: "2024-11-06T23:04:01.121866913Z" dependencies: - condition: global.config.enabled name: config @@ -3380,7 +3380,7 @@ entries: catalog.cattle.io/release-name: gluu apiVersion: v2 appVersion: 5.0.0 - created: "2024-11-05T23:03:51.842911288Z" + created: "2024-11-06T23:04:01.112943565Z" dependencies: - condition: global.config.enabled name: config @@ -3485,7 +3485,7 @@ entries: catalog.cattle.io/release-name: gluu apiVersion: v2 appVersion: 5.0.0 - created: "2024-11-05T23:03:51.833514302Z" + created: "2024-11-06T23:04:01.103977482Z" dependencies: - condition: global.config.enabled name: config @@ -3590,7 +3590,7 @@ entries: catalog.cattle.io/release-name: gluu apiVersion: v2 appVersion: 5.0.0 - created: "2024-11-05T23:03:51.82425637Z" + created: "2024-11-06T23:04:01.094919052Z" dependencies: - condition: global.config.enabled name: config @@ -3676,10 +3676,10 @@ entries: catalog.cattle.io/release-name: gluu-all-in-one apiVersion: v2 appVersion: 5.1.6-dev - created: "2024-11-05T23:03:52.187701675Z" + created: "2024-11-06T23:04:01.45495543Z" description: Gluu Access and Identity Management All-in-One Chart. This chart deploys the selected janssen microservice all in one deployment. - digest: 3d81fe5320d25bb3234efa891a1ac76d6e017aaded0b0289260ef762085eac56 + digest: ede2626e2043a0228b2e47f296657466a52b83fd1f25d2ea6eee827a43887b2f home: https://docs.gluu.org icon: https://gluu.org/docs/gluu-server/favicon.ico kubeVersion: '>=v1.22.0-0' @@ -3705,7 +3705,7 @@ entries: catalog.cattle.io/release-name: gluu-all-in-one apiVersion: v2 appVersion: 5.1.5 - created: "2024-11-05T23:03:52.184695588Z" + created: "2024-11-06T23:04:01.452424395Z" description: Gluu Access and Identity Management All-in-One Chart. This chart deploys the selected janssen microservice all in one deployment. digest: 315306c90ec1b86b89e332b5886986975989b9ef85d94bf4fb91811c17f740cb @@ -3734,7 +3734,7 @@ entries: catalog.cattle.io/release-name: gluu-all-in-one apiVersion: v2 appVersion: 5.1.5-dev - created: "2024-11-05T23:03:52.182590217Z" + created: "2024-11-06T23:04:01.450296973Z" description: Gluu Access and Identity Management All-in-One Chart. This chart deploys the selected janssen microservice all in one deployment. digest: 83a01c73321e167e19071b294466d8b7470b3073a4cea3eaa675c4ce046ab8ea @@ -3763,7 +3763,7 @@ entries: catalog.cattle.io/release-name: gluu-all-in-one apiVersion: v2 appVersion: 5.1.4 - created: "2024-11-05T23:03:52.180458555Z" + created: "2024-11-06T23:04:01.448227148Z" description: Gluu Access and Identity Management All-in-One Chart. This chart deploys the selected janssen microservice all in one deployment. digest: af6fcc0ba0858a92e6b80aaa5e12bc1d51782c592eb3c293f91f0e1c12d08bb4 @@ -3792,7 +3792,7 @@ entries: catalog.cattle.io/release-name: gluu-all-in-one apiVersion: v2 appVersion: 5.1.4-dev - created: "2024-11-05T23:03:52.178327716Z" + created: "2024-11-06T23:04:01.445659704Z" description: Gluu Access and Identity Management All-in-One Chart. This chart deploys the selected janssen microservice all in one deployment. digest: 57808da241c9be85c91125cb6e7a1e2c18ee1eb8180e23ab7d2049abdbfc12ae @@ -3821,7 +3821,7 @@ entries: catalog.cattle.io/release-name: gluu-all-in-one apiVersion: v2 appVersion: 5.1.3 - created: "2024-11-05T23:03:52.175324981Z" + created: "2024-11-06T23:04:01.443325145Z" description: Gluu Access and Identity Management All-in-One Chart. This chart deploys the selected janssen microservice all in one deployment. digest: 39973afe0c5e3b81d6310a60d8b60300175b8e416a60cd0d19f900fe02f00f86 @@ -3850,7 +3850,7 @@ entries: catalog.cattle.io/release-name: gluu-all-in-one apiVersion: v2 appVersion: 5.1.3-dev - created: "2024-11-05T23:03:52.173242603Z" + created: "2024-11-06T23:04:01.441145495Z" description: Gluu Access and Identity Management All-in-One Chart. This chart deploys the selected janssen microservice all in one deployment. digest: 782168d240a84743337ca19cfcee81c6df56af625940ab283da3b7cb7e6305e7 @@ -3879,7 +3879,7 @@ entries: catalog.cattle.io/release-name: gluu-all-in-one apiVersion: v2 appVersion: 5.1.2 - created: "2024-11-05T23:03:52.171129657Z" + created: "2024-11-06T23:04:01.439009247Z" description: Gluu Access and Identity Management All-in-One Chart. This chart deploys the selected janssen microservice all in one deployment. digest: bccbfe33f1a09be7e5b8f53acc05a66b3d8d7bad47d9b72870522ea23b808575 @@ -3908,7 +3908,7 @@ entries: catalog.cattle.io/release-name: gluu-all-in-one apiVersion: v2 appVersion: 5.1.2 - created: "2024-11-05T23:03:52.16876345Z" + created: "2024-11-06T23:04:01.436305011Z" description: Gluu Access and Identity Management All-in-One Chart. This chart deploys the selected janssen microservice all in one deployment. digest: d8176a5e2ae93667977d1cd7f776d60decae13ed69293e905ca40109cba2392c @@ -3937,7 +3937,7 @@ entries: catalog.cattle.io/release-name: gluu-all-in-one apiVersion: v2 appVersion: 5.1.1 - created: "2024-11-05T23:03:52.166312375Z" + created: "2024-11-06T23:04:01.434288857Z" description: Gluu Access and Identity Management All-in-One Chart. This chart deploys the selected janssen microservice all in one deployment. digest: 0f8cb67a0263cb3995746b2add018baac6345a85173559f42c966de3900ca209 @@ -3966,7 +3966,7 @@ entries: catalog.cattle.io/release-name: gluu-all-in-one apiVersion: v2 appVersion: 5.1.1 - created: "2024-11-05T23:03:52.164411059Z" + created: "2024-11-06T23:04:01.432327595Z" description: Gluu Access and Identity Management All-in-One Chart. This chart deploys the selected janssen microservice all in one deployment. digest: 16df387e8628114b4ada11251da04d228bb5a56d8bcd1dac8eb0a8bfc4737b6c @@ -3995,7 +3995,7 @@ entries: catalog.cattle.io/release-name: gluu-all-in-one apiVersion: v2 appVersion: 5.1.0 - created: "2024-11-05T23:03:52.162463214Z" + created: "2024-11-06T23:04:01.430374759Z" description: Gluu Access and Identity Management All-in-One Chart. This chart deploys the selected janssen microservice all in one deployment. digest: 4f04600dfe57ea63f0cc1dcb1ac5e5aaeaea301b5d6d88c1465e6e7b26c63681 @@ -4024,7 +4024,7 @@ entries: catalog.cattle.io/release-name: gluu-all-in-one apiVersion: v2 appVersion: 5.0.22 - created: "2024-11-05T23:03:52.160337813Z" + created: "2024-11-06T23:04:01.42763983Z" description: Gluu Access and Identity Management All-in-One Chart. This chart deploys the selected janssen microservice all in one deployment. digest: 89f620286a1bf1f3d660dde987ef71d8591b4b56383f3d2a4a63a5d3a20dd0ab @@ -4053,7 +4053,7 @@ entries: catalog.cattle.io/release-name: gluu-all-in-one apiVersion: v2 appVersion: 5.0.0 - created: "2024-11-05T23:03:52.157681682Z" + created: "2024-11-06T23:04:01.425746465Z" description: Gluu Access and Identity Management All-in-One Chart. This chart deploys the selected janssen microservice all in one deployment. digest: 7933c1944cee8fe7081fd20b458c393049591779607443c00adc78700f0b2818 @@ -4083,7 +4083,7 @@ entries: catalog.cattle.io/release-name: gluu-all-in-one apiVersion: v2 appVersion: 5.0.0 - created: "2024-11-05T23:03:52.155815011Z" + created: "2024-11-06T23:04:01.423877305Z" description: Gluu Access and Identity Management All-in-One Chart. This chart deploys the selected janssen microservice all in one deployment. digest: 1c7a5df81b9750989e471d6313828834f67a8c01e9407cee7c9840860fbe6925 @@ -4113,7 +4113,7 @@ entries: catalog.cattle.io/release-name: gluu-all-in-one apiVersion: v2 appVersion: 5.0.0 - created: "2024-11-05T23:03:52.154043589Z" + created: "2024-11-06T23:04:01.422087523Z" description: Gluu Access and Identity Management All-in-One Chart. This chart deploys the selected janssen microservice all in one deployment. digest: 322a1b4de45e30947f3a319d0ede7e9f466c3687bb7a8795a7dfcdb649ab98d7 @@ -4145,7 +4145,7 @@ entries: catalog.cattle.io/release-name: gluu-all-in-one apiVersion: v2 appVersion: 5.0.0 - created: "2024-11-05T23:03:52.152272839Z" + created: "2024-11-06T23:04:01.420342385Z" description: Gluu Access and Identity Management All-in-One Chart. This chart deploys the selected janssen microservice all in one deployment. digest: ab0b9ca96bf41aa4a1689f4c11f60d9420d68072b348879c76737d8e87fedf61 @@ -4162,4 +4162,4 @@ entries: urls: - gluu-all-in-one-1.0.20.tgz version: 1.0.20 -generated: "2024-11-05T23:03:51.81488181Z" +generated: "2024-11-06T23:04:01.08534954Z" diff --git a/v5.1.6.nightly/admin/kubernetes-ops/upgrade/index.html b/v5.1.6.nightly/admin/kubernetes-ops/upgrade/index.html index f121a720e..b70f5e404 100644 --- a/v5.1.6.nightly/admin/kubernetes-ops/upgrade/index.html +++ b/v5.1.6.nightly/admin/kubernetes-ops/upgrade/index.html @@ -1782,7 +1782,7 @@

Upgrade

  • Apply your upgrade:

    -

    helm upgrade <flex-release-name> gluu-flex/gluu -n <namespace> -f override.yaml --version=replace-flex-version

    +

    helm upgrade <flex-release-name> gluu-flex/gluu -n <namespace> -f override.yaml --version=5.1.6.nightly

  • diff --git a/v5.1.6.nightly/admin/recipes/getting-started-rancher/index.html b/v5.1.6.nightly/admin/recipes/getting-started-rancher/index.html index 87c100be7..c2a7d33a1 100644 --- a/v5.1.6.nightly/admin/recipes/getting-started-rancher/index.html +++ b/v5.1.6.nightly/admin/recipes/getting-started-rancher/index.html @@ -2544,7 +2544,7 @@

    Successful InstallationClick on Install on the right side of the window.
  • Change the namespace from default to gluu, then click on Next.
  • Scroll through the sections to get familiar with the options. For minimal setup follow with the next instructions.
  • -
  • Add License SSA. Before initiating the setup, please obtain an SSA for Flex trial, after which you will issued a JWT.
  • +
  • Add License SSA. Before initiating the setup, please obtain an SSA for Flex trial, after which you will issued a JWT.
  • Click on the Persistence section. Change SQL database host uri to postgresql.postgres.svc.cluster.local in the case of PostgreSQL or my-release-mysql.gluu.svc.cluster.local in the case of MySQL. Also set SQL database username,SQL password, and SQL database name to the values you used during the database installation.
  • To enable Casa and the Admin UI, navigate to the Optional Services section and check the Enable casa and boolean flag to enable admin UI boxes. You can also enable different services like Client API and Jackrabbit.
  • Click on the section named Ingress and enable all the endpoints. You might add LB IP or address if you don't have FQDN for Gluu.
  • diff --git a/v5.1.6.nightly/install/docker-install/quick-start/index.html b/v5.1.6.nightly/install/docker-install/quick-start/index.html index eb4343554..086aa9201 100644 --- a/v5.1.6.nightly/install/docker-install/quick-start/index.html +++ b/v5.1.6.nightly/install/docker-install/quick-start/index.html @@ -1895,7 +1895,7 @@

    Installset of environment variables. These environment variables can be set to customize installation as per the need. If not set, the installer uses default values.

    Run this command to start the installation:

    -
    wget https://raw.githubusercontent.com/GluuFederation/flex/vreplace-flex-version/automation/startflexmonolithdemo.sh && chmod u+x startflexmonolithdemo.sh && sudo bash startflexmonolithdemo.sh demoexample.gluu.org MYSQL
    +
    wget https://raw.githubusercontent.com/GluuFederation/flex/v5.1.6.nightly/automation/startflexmonolithdemo.sh && chmod u+x startflexmonolithdemo.sh && sudo bash startflexmonolithdemo.sh demoexample.gluu.org MYSQL
     

    Console messages like below confirms the successful installation:

    [+] Running 3/3
    diff --git a/v5.1.6.nightly/install/helm-install/amazon-eks/index.html b/v5.1.6.nightly/install/helm-install/amazon-eks/index.html
    index f8c86905f..2679896e3 100644
    --- a/v5.1.6.nightly/install/helm-install/amazon-eks/index.html
    +++ b/v5.1.6.nightly/install/helm-install/amazon-eks/index.html
    @@ -1992,7 +1992,7 @@ 

    System RequirementsInitial Setup#

    1. -

      Before initiating the setup, please obtain an SSA for Flex trial, after which you will issued a JWT.

      +

      Before initiating the setup, please obtain an SSA for Flex trial, after which you will issued a JWT.

    2. Install aws cli

      diff --git a/v5.1.6.nightly/install/helm-install/google-gke/index.html b/v5.1.6.nightly/install/helm-install/google-gke/index.html index be1c0b8be..aa3097edd 100644 --- a/v5.1.6.nightly/install/helm-install/google-gke/index.html +++ b/v5.1.6.nightly/install/helm-install/google-gke/index.html @@ -1992,7 +1992,7 @@

      System RequirementsInitial Setup#

      1. -

        Before initiating the setup, please obtain an SSA for Flex trial, after which you will issued a JWT.

        +

        Before initiating the setup, please obtain an SSA for Flex trial, after which you will issued a JWT.

      2. Enable GKE API if not enabled yet.

        diff --git a/v5.1.6.nightly/install/helm-install/local/index.html b/v5.1.6.nightly/install/helm-install/local/index.html index f988d3e8e..04886de80 100644 --- a/v5.1.6.nightly/install/helm-install/local/index.html +++ b/v5.1.6.nightly/install/helm-install/local/index.html @@ -1961,11 +1961,11 @@

        System RequirementsInstallation Steps#

        -

        Before initiating the setup, please obtain an SSA for Flex trial, after which you will issued a JWT.

        +

        Before initiating the setup, please obtain an SSA for Flex trial, after which you will issued a JWT.

        Start a fresh Ubuntu 18.04/20.04/22.04 VM with ports 443 and 80 open. Then execute the following:

        sudo su -
         
        -
        wget https://raw.githubusercontent.com/GluuFederation/flex/vreplace-flex-version/automation/startflexdemo.sh && chmod u+x startflexdemo.sh && ./startflexdemo.sh
        +
        wget https://raw.githubusercontent.com/GluuFederation/flex/v5.1.6.nightly/automation/startflexdemo.sh && chmod u+x startflexdemo.sh && ./startflexdemo.sh
         

        This will install Docker, Microk8s, Helm and Gluu with the default settings that can be found inside values.yaml.

        The installer will automatically add a record to your hosts record in the VM but if you want to access the endpoints outside the VM you must map the ip of the instance running Ubuntu to the FQDN you provided and then access the endpoints at your browser such in the example in the table below.

        diff --git a/v5.1.6.nightly/install/helm-install/microsoft-azure/index.html b/v5.1.6.nightly/install/helm-install/microsoft-azure/index.html index 8d115aa2e..83127adb7 100644 --- a/v5.1.6.nightly/install/helm-install/microsoft-azure/index.html +++ b/v5.1.6.nightly/install/helm-install/microsoft-azure/index.html @@ -1992,7 +1992,7 @@

        System RequirementsInitial Setup#

        1. -

          Before initiating the setup, please obtain an SSA for Flex trial, after which you will issued a JWT.

          +

          Before initiating the setup, please obtain an SSA for Flex trial, after which you will issued a JWT.

        2. Install Azure CLI

          diff --git a/v5.1.6.nightly/install/helm-install/rancher/index.html b/v5.1.6.nightly/install/helm-install/rancher/index.html index 4e6b5285d..df9fe124d 100644 --- a/v5.1.6.nightly/install/helm-install/rancher/index.html +++ b/v5.1.6.nightly/install/helm-install/rancher/index.html @@ -1813,7 +1813,7 @@

          Install Gluu Server Using Rancher Marketplace#

          -

          For a more generic Gluu Flex installation on Rancher, you can follow this comprehensive guide.

          +

          For a more generic Gluu Flex installation on Rancher, you can follow this comprehensive guide.

          Also, there are multiple Rancher installation options. For this quick start setup we will use a single node Kubernetes install in docker with a self-signed certificate.

          Installation Steps#

          @@ -1822,7 +1822,7 @@

          Installation Stepsexample on how to do that.

            -
          1. Before initiating the setup, please obtain an SSA for Flex trial, after which you will issued a JWT.
          2. +
          3. Before initiating the setup, please obtain an SSA for Flex trial, after which you will issued a JWT.
          4. Provision a Linux 4 CPU, 16 GB RAM, and 50GB SSD VM with ports 443 and 80 open. Save the VM IP address. For development environments, the VM can be set up using VMWare Workstation Player or VirtualBox with Ubuntu 20.04 operating system running on a VM.
          5. Install Docker.
          6. Execute diff --git a/v5.1.6.nightly/install/vm-install/rhel/index.html b/v5.1.6.nightly/install/vm-install/rhel/index.html index e4ee22228..6551514da 100644 --- a/v5.1.6.nightly/install/vm-install/rhel/index.html +++ b/v5.1.6.nightly/install/vm-install/rhel/index.html @@ -2041,7 +2041,7 @@

            Download and Verify the Release
            • Download the release package from the Github Flex Releases -
              wget https://github.com/GluuFederation/flex/releases/download/vreplace-flex-version/flex-replace-flex-version-el8.x86_64.rpm -P /tmp
              +
              wget https://github.com/GluuFederation/flex/releases/download/v5.1.6.nightly/flex-5.1.6.nightly-el8.x86_64.rpm -P /tmp
               
            • GPG key is used to ensure the authenticity of the downloaded package during the installation process. If the key is not found, the installation step would fail. Use the commands below to download and @@ -2053,18 +2053,18 @@

              Download and Verify the Release
              sudo rpm -import automation-flex-public-gpg.asc
               

            • Verify the integrity of the downloaded package using published sha256sum. Download the sha256sum file for the package -
              wget https://github.com/GluuFederation/flex/releases/download/vreplace-flex-version/flex-replace-flex-version-el8.x86_64.rpm.sha256sum  -P /tmp
              +
              wget https://github.com/GluuFederation/flex/releases/download/v5.1.6.nightly/flex-5.1.6.nightly-el8.x86_64.rpm.sha256sum  -P /tmp
               
              Run the command below from the directory where the downloaded package and the .sha256sum files are located.
              cd /tmp;
              -sha256sum -c flex-replace-flex-version-el8.x86_64.rpm.sha256sum;
              +sha256sum -c flex-5.1.6.nightly-el8.x86_64.rpm.sha256sum;
               
              Output similar to below should confirm the integrity of the downloaded package. -
              flex-replace-flex-version-el8.x86_64.rpm : ok
              +
              flex-5.1.6.nightly-el8.x86_64.rpm : ok
               

            Install the Release Package#

            -
            sudo yum install ./flex-replace-flex-version-el8.x86_64.rpm
            +
            sudo yum install ./flex-5.1.6.nightly-el8.x86_64.rpm
             

            Run the setup script#

            Execute the setup script with command below: diff --git a/v5.1.6.nightly/install/vm-install/suse/index.html b/v5.1.6.nightly/install/vm-install/suse/index.html index 45a8439c6..6971fb0c5 100644 --- a/v5.1.6.nightly/install/vm-install/suse/index.html +++ b/v5.1.6.nightly/install/vm-install/suse/index.html @@ -2003,7 +2003,7 @@

            Download and Verify the Release
            • Download the release package from the GitHub FLEX Releases -

              wget https://github.com/GluuFederation/flex/releases/download/vreplace-flex-version/flex-replace-flex-version-suse15.x86_64.rpm -P ~/
              +
              wget https://github.com/GluuFederation/flex/releases/download/v5.1.6.nightly/flex-5.1.6.nightly-suse15.x86_64.rpm -P ~/
               

            • @@ -2019,21 +2019,21 @@

              Download and Verify the Release

            • Verify the integrity of the downloaded package using published sha256sum. Download the sha256sum file for the package -

              wget https://github.com/GluuFederation/flex/releases/download/vreplace-flex-version/flex-replace-flex-version-suse15.x86_64.rpm.sha256sum  -P ~/
              +
              wget https://github.com/GluuFederation/flex/releases/download/v5.1.6.nightly/flex-5.1.6.nightly-suse15.x86_64.rpm.sha256sum  -P ~/
               

            • Verify package integrity -

              sha256sum -c flex-replace-flex-version-suse15.x86_64.rpm.sha256sum
              +
              sha256sum -c flex-5.1.6.nightly-suse15.x86_64.rpm.sha256sum
               
              You should see: -
              flex-replace-flex-version-suse15.x86_64.rpm: ok
              +
              flex-5.1.6.nightly-suse15.x86_64.rpm: ok
               

            Install the Release Package#

            Use SUSE zypper to install -

            sudo zypper install ~/flex-replace-flex-version-suse15.x86_64.rpm
            +
            sudo zypper install ~/flex-5.1.6.nightly-suse15.x86_64.rpm
             

            Run the setup script#

              diff --git a/v5.1.6.nightly/install/vm-install/ubuntu/index.html b/v5.1.6.nightly/install/vm-install/ubuntu/index.html index fdef14e86..ac80880e0 100644 --- a/v5.1.6.nightly/install/vm-install/ubuntu/index.html +++ b/v5.1.6.nightly/install/vm-install/ubuntu/index.html @@ -2030,10 +2030,10 @@

              Download and Verify the Release

              Download the release package from the GitHub FLEX Releases. Choose the correct command from below based on the OS version.

              #Ubuntu 22.04
              -wget https://github.com/GluuFederation/flex/releases/download/vreplace-flex-version/flex_replace-flex-version.ubuntu22.04_amd64.deb -P /tmp
              +wget https://github.com/GluuFederation/flex/releases/download/v5.1.6.nightly/flex_5.1.6.nightly.ubuntu22.04_amd64.deb -P /tmp
               
              #Ubuntu 20.04
              -wget https://github.com/GluuFederation/flex/releases/download/vreplace-flex-version/flex_replace-flex-version.ubuntu20.04_amd64.deb -P /tmp
              +wget https://github.com/GluuFederation/flex/releases/download/v5.1.6.nightly/flex_5.1.6.nightly.ubuntu20.04_amd64.deb -P /tmp
               

            • @@ -2051,34 +2051,34 @@

              Download and Verify the Release

              Verify the integrity of the downloaded package using published sha256sum. Download the sha256sum file for the package. Choose the correct command from below based on the OS version.

              #Ubuntu 22.04
              -wget https://github.com/GluuFederation/flex/releases/download/vreplace-flex-version/flex_replace-flex-version.ubuntu22.04_amd64.deb.sha256sum  -P /tmp
              +wget https://github.com/GluuFederation/flex/releases/download/v5.1.6.nightly/flex_5.1.6.nightly.ubuntu22.04_amd64.deb.sha256sum  -P /tmp
               
              #Ubuntu 20.04
              -wget https://github.com/GluuFederation/flex/releases/download/vreplace-flex-version/flex_replace-flex-version.ubuntu20.04_amd64.deb.sha256sum  -P /tmp
              +wget https://github.com/GluuFederation/flex/releases/download/v5.1.6.nightly/flex_5.1.6.nightly.ubuntu20.04_amd64.deb.sha256sum  -P /tmp
               
              Verify package integrity of the package that has been downloaded by checking hash. Run the command below from the directory where the downloaded package and the .sha256sum files are located. Choose the correct command from below based on the OS version.
              #Ubuntu 22.04
               cd /tmp
              -sha256sum -c flex_replace-flex-version.ubuntu22.04_amd64.deb.sha256sum
              +sha256sum -c flex_5.1.6.nightly.ubuntu22.04_amd64.deb.sha256sum
               
              #Ubuntu 20.04
               cd /tmp
              -sha256sum -c flex_replace-flex-version.ubuntu20.04_amd64.deb.sha256sum
              +sha256sum -c flex_5.1.6.nightly.ubuntu20.04_amd64.deb.sha256sum
               
              Output similar to below should confirm the integrity of the downloaded package. -
              flex_replace-flex-version.ubuntu<version>_amd64.deb: ok
              +
              flex_5.1.6.nightly.ubuntu<version>_amd64.deb: ok
               

            Install the Release Package#

            Choose the correct command from below based on the OS version.

            #Ubuntu 22.04
            -apt install -y /tmp/flex_replace-flex-version.ubuntu22.04_amd64.deb
            +apt install -y /tmp/flex_5.1.6.nightly.ubuntu22.04_amd64.deb
             
            #Ubuntu 20.04
            -apt install -y /tmp/flex_replace-flex-version.ubuntu20.04_amd64.deb
            +apt install -y /tmp/flex_5.1.6.nightly.ubuntu20.04_amd64.deb
             

            Run the setup script#

            Execute the setup script with command below: diff --git a/v5.1.6.nightly/install/vm-install/vm-requirements/index.html b/v5.1.6.nightly/install/vm-install/vm-requirements/index.html index 9c4337d6d..3e4156d03 100644 --- a/v5.1.6.nightly/install/vm-install/vm-requirements/index.html +++ b/v5.1.6.nightly/install/vm-install/vm-requirements/index.html @@ -1864,7 +1864,7 @@

            Supported Versions

            Note

            -

            This document is intended exclusively for dev and staging environments. For production deployment on a VM, refer to this documentation which utilizes Rancher and Helm deployments.

            +

            This document is intended exclusively for dev and staging environments. For production deployment on a VM, refer to this documentation which utilizes Rancher and Helm deployments.

            Hardware Requirements#

            A single-VM deployment is where all services are running on one server. Although, the requirements can vary based on the size of the data and the required concurrency, the following guidelines can help you plan:

            diff --git a/v5.1.6.nightly/openbanking/index.html b/v5.1.6.nightly/openbanking/index.html index f207eaddf..a3cfbed86 100644 --- a/v5.1.6.nightly/openbanking/index.html +++ b/v5.1.6.nightly/openbanking/index.html @@ -1767,7 +1767,7 @@

            OverviewInstallation Section has more details about it.

            +

            This is a cloud-native distribution. Cloud-native is essential for auto-scaling, high availability, and operational automation. For development and testing we also support its VM distribution, where the Installation Section has more details about it.

            This distribution of Gluu is based on the Linux Foundation Janssen Project at the Linux Foundation, the most certified OpenID Platform available.

            Components#

            component topology

            diff --git a/v5.1.6.nightly/openbanking/install-cn/index.html b/v5.1.6.nightly/openbanking/install-cn/index.html index 3dc87c8da..89781793f 100644 --- a/v5.1.6.nightly/openbanking/install-cn/index.html +++ b/v5.1.6.nightly/openbanking/install-cn/index.html @@ -1990,7 +1990,7 @@

            Install using Helm(production-ready)

          7. -

            Based on the provider/platform you're using, you can follow the docs to install your platform prerequistes, nginx-ingress, and the yaml changes needed in override.yaml based on the Gluu persistence choosed.

            +

            Based on the provider/platform you're using, you can follow the docs to install your platform prerequistes, nginx-ingress, and the yaml changes needed in override.yaml based on the Gluu persistence choosed.

          8. To enable mTLS in ingress-nginx, add the following to your override.yaml: @@ -2137,7 +2137,7 @@

            Install on microK8s(development/t

            Running this script will install the Gluu Open Banking Platform along with th mysql persistence.

            After running the script, you can go ahead and test the setup.

            Testing the setup#

            -

            After successful installation, you can access and test the Gluu Open Banking Platform using either curl or Jans-CLI.

            +

            After successful installation, you can access and test the Gluu Open Banking Platform using either curl or Jans-CLI.

            Changing the signing key kid for the AS dynamically#

            1. diff --git a/v5.1.6.nightly/openbanking/install-vm/index.html b/v5.1.6.nightly/openbanking/install-vm/index.html index 29e81c63e..de5fa27fa 100644 --- a/v5.1.6.nightly/openbanking/install-vm/index.html +++ b/v5.1.6.nightly/openbanking/install-vm/index.html @@ -2069,7 +2069,7 @@

              Accessing the Platform#

              -

              After successful installation, access the Gluu Open Banking Platform using either jans-cli or curl.

              +

              After successful installation, access the Gluu Open Banking Platform using either jans-cli or curl.


              diff --git a/v5.1.6.nightly/search/search_index.json b/v5.1.6.nightly/search/search_index.json index 8e3210ec3..3d3a86d67 100644 --- a/v5.1.6.nightly/search/search_index.json +++ b/v5.1.6.nightly/search/search_index.json @@ -1 +1 @@ -{"config":{"indexing":"full","lang":["en"],"min_search_length":3,"prebuild_index":false,"separator":"[\\s\\-]+"},"docs":[{"location":"","text":"Gluu Flex Documentation # Introduction # Designed from the ground up to support cloud-native deployments, Gluu Flex is a self-hosted software stack to enable your organization to build a world-class digital identity platform to authenticate both people and software. With Helm charts available out of the box, Gluu Flex can handle the most demanding requirements for concurrency. Thanks to cloud-native auto-scaling and zero downtime updates, you can build a robust, multi-datacenter topology. You can take advantage of new cloud databases like Amazon Aurora and Google Spanner. Common use cases include: Single sign-on (SSO) Mobile authentication API access management Two-factor authentication (2FA) Customer identity and access management (CIAM) Identity federation Built on Janssen # Gluu Flex is a downstream product of the Linux Foundation Janssen Project . It was created for enterprise customers who want a commercially supported distribution, plus some additional tools to ease administration. Harness Low Code Authentication Flows with Agama # Gluu Flex uses Agama to offer an alternative way to build web-based authentication flows. Traditionally, person authentication flows are defined in the server with jython scripts that adhere to a predefined API. With Agama, flows are coded using a DSL (domain specific language) designed for the sole purpose of writing web flows. Agama flows are simpler, more intuitive, and quicker to build. Support # The Gluu Flex contract includes guaranteed response times and consultative support via our support portal . Looking for older documentation versions? # The Janssen Project posts the last five versions of the documentation. If you are looking for older versions, you can find them unprocessed in the docs folder. Select the version of choice from the tag dropdown in GitHub. If you want to process them you may do so by following the steps below : Testing Documentation Changes Locally # While contributing documentation to official Gluu documentation it is important to make sure that documents meet style guidelines and have been proofread to remove any typographical or grammatical errors. Gluu uses Material for MkDocs to create the documentation site. Before new content is pushed to the repository on GitHub, it should be tested locally by the author. Author can do this by deploying Material for MkDocs locally. High-level steps involve: Install Material for MkDocs Install required plugins Preview as you write","title":"Overview"},{"location":"#gluu-flex-documentation","text":"","title":"Gluu Flex Documentation"},{"location":"#introduction","text":"Designed from the ground up to support cloud-native deployments, Gluu Flex is a self-hosted software stack to enable your organization to build a world-class digital identity platform to authenticate both people and software. With Helm charts available out of the box, Gluu Flex can handle the most demanding requirements for concurrency. Thanks to cloud-native auto-scaling and zero downtime updates, you can build a robust, multi-datacenter topology. You can take advantage of new cloud databases like Amazon Aurora and Google Spanner. Common use cases include: Single sign-on (SSO) Mobile authentication API access management Two-factor authentication (2FA) Customer identity and access management (CIAM) Identity federation","title":"Introduction"},{"location":"#built-on-janssen","text":"Gluu Flex is a downstream product of the Linux Foundation Janssen Project . It was created for enterprise customers who want a commercially supported distribution, plus some additional tools to ease administration.","title":"Built on Janssen"},{"location":"#harness-low-code-authentication-flows-with-agama","text":"Gluu Flex uses Agama to offer an alternative way to build web-based authentication flows. Traditionally, person authentication flows are defined in the server with jython scripts that adhere to a predefined API. With Agama, flows are coded using a DSL (domain specific language) designed for the sole purpose of writing web flows. Agama flows are simpler, more intuitive, and quicker to build.","title":"Harness Low Code Authentication Flows with Agama"},{"location":"#support","text":"The Gluu Flex contract includes guaranteed response times and consultative support via our support portal .","title":"Support"},{"location":"#looking-for-older-documentation-versions","text":"The Janssen Project posts the last five versions of the documentation. If you are looking for older versions, you can find them unprocessed in the docs folder. Select the version of choice from the tag dropdown in GitHub. If you want to process them you may do so by following the steps below :","title":"Looking for older documentation versions?"},{"location":"#testing-documentation-changes-locally","text":"While contributing documentation to official Gluu documentation it is important to make sure that documents meet style guidelines and have been proofread to remove any typographical or grammatical errors. Gluu uses Material for MkDocs to create the documentation site. Before new content is pushed to the repository on GitHub, it should be tested locally by the author. Author can do this by deploying Material for MkDocs locally. High-level steps involve: Install Material for MkDocs Install required plugins Preview as you write","title":"Testing Documentation Changes Locally"},{"location":"CHANGELOG/","text":"Changelog # 5.0.0-21 (2023-12-18) # Bug Fixes # prepare for 5.0.0-21 release ( cee44ca ) 5.0.0-20 (2023-11-16) # Features # aio chart ( #1436 ) ( a20a695 ) Bug Fixes # docs: update casa base URI ( #1440 ) ( 495536c ) prepare for 5.0.0-20 release ( f74643c ) 5.0.0-19 (2023-10-12) # Features # docs: remove Casa files from Flex ( a5b7fcd ) Bug Fixes # docs: remove Casa image assets ( 0b9f0b4 ) docs: update docs w.r.t casa move to Jans ( 5b7d3fd ) docs: update docs w.r.t casa move to Jans ( 16f647c ) prepare for 5.0.0-19 release ( 2d8e13d ) 5.0.0-18 (2023-09-23) # Features # adding configuration and logs details ( d136f3d ) updating configuration docs ( a1933e3 ) Bug Fixes # prepare for 5.0.0-18 release ( 29f822f ) prepare for 5.0.0-18 release ( 4af69cb ) versioning ( 1abf437 ) 5.0.0-16 (2023-08-14) # Bug Fixes # prepare for 5.0.0-16 release ( 699d534 ) 5.0.0-15 (2023-07-14) # Features # adding tags ( 7841e03 ) documentation of admin-ui #1063 ( 3cf1e7b ) documentation of admin-ui #1063 ( 48233d3 ) edit flex license contents ( 8d7f749 ) making changes as per review comments ( 1bcd39b ) making changes as per review comments ( 5c636fb ) Bug Fixes # doc: added How to configure SuperGluu in Flex ( 6b7beef ) doc: adding SG screenshot - 2 ( e06bd79 ) doc: adding SG screenshot-1 ( b581a03 ) doc: enable SG - 2 ( d86ec85 ) doc: Flex SG doc review - How to Use SuperGluu ( f564dd1 ) doc: hiding ad removal related doc ( 5354e84 ) doc: how to enable SG in Flex-UI ( 4851205 ) doc: index page flex ( 7d48422 ) doc: removing key list from user record info ( 01b671a ) docs: flex-ui SG -- Compatability ( f78c46a ) doc: SG flex - How to use Super Gluu-1 ( e07641c ) doc: sg flex - how to use Super Gluu-screenshot location ( 7798023 ) doc: sg workflows ( 601b237 ) docs: test SG authentication ( 32f6b24 ) doc: test authentication SG ( 6d0f550 ) doc: Test authentication user guide ( a554646 ) doc: uploading modified screenshot ( 0e9e0cf ) prepare for 5.0.0-15 release ( 664553a ) 5.0.0-14 (2023-06-12) # Bug Fixes # prepare for 5.0.0-14 release ( 9481f55 ) 5.0.0-13 (2023-05-12) # Bug Fixes # admin-ui: add apply button ( d334103 ) blockUI converted to functional component ( 4b8e7bd ) email_2fa_core/install.bat has been removed; ( f27e461 ) prepare for 5.0.13 release ( 8578827 ) profile details is distorted when multiple roles assigned to the user ( e4603d8 ) revert prod webpack config of static & fonts files ( 96fa135 ) 5.0.0-12 (2023-04-18) # Bug Fixes # prepare for 5.0.12 release ( 994c985 ) 5.0.0-11 (2023-04-06) # Bug Fixes # prepare for 5.0.11 release ( d3cc35a ) 5.0.0-10 (2023-03-16) # Bug Fixes # add cn license enforcment to chart ( 55fb0c9 ) prepare for 5.0.10 release ( 1ffcbc7 ) 5.0.0-9 (2023-03-09) # Bug Fixes # docs: ubuntu install download location ( bb3a5cd ) prepare for 5.0.0-9 release ( 716d309 ) 5.0.0-8 (2023-03-02) # Bug Fixes # prepare for 5.0.0-8 release ( 29e0cbb ) 5.0.0-7 (2023-02-22) # Bug Fixes # prepare for 5.0.0-7 release ( 7f96937 ) 5.0.0-4 (2022-12-08) # Bug Fixes # getting ready for a release ( a0de091 ) 5.0.0-3 (2022-11-08) # Features # admin-ui: reviewed previously updated dependencies #416 ( ab81760 ) Bug Fixes # getting ready to release 5.0.0-3 ( e8f3ecc ) Miscellaneous Chores # release 5.0.0-2 ( 06c6e64 )","title":"Changelog"},{"location":"CHANGELOG/#changelog","text":"","title":"Changelog"},{"location":"CHANGELOG/#500-21-2023-12-18","text":"","title":"5.0.0-21 (2023-12-18)"},{"location":"CHANGELOG/#bug-fixes","text":"prepare for 5.0.0-21 release ( cee44ca )","title":"Bug Fixes"},{"location":"CHANGELOG/#500-20-2023-11-16","text":"","title":"5.0.0-20 (2023-11-16)"},{"location":"CHANGELOG/#features","text":"aio chart ( #1436 ) ( a20a695 )","title":"Features"},{"location":"CHANGELOG/#bug-fixes_1","text":"docs: update casa base URI ( #1440 ) ( 495536c ) prepare for 5.0.0-20 release ( f74643c )","title":"Bug Fixes"},{"location":"CHANGELOG/#500-19-2023-10-12","text":"","title":"5.0.0-19 (2023-10-12)"},{"location":"CHANGELOG/#features_1","text":"docs: remove Casa files from Flex ( a5b7fcd )","title":"Features"},{"location":"CHANGELOG/#bug-fixes_2","text":"docs: remove Casa image assets ( 0b9f0b4 ) docs: update docs w.r.t casa move to Jans ( 5b7d3fd ) docs: update docs w.r.t casa move to Jans ( 16f647c ) prepare for 5.0.0-19 release ( 2d8e13d )","title":"Bug Fixes"},{"location":"CHANGELOG/#500-182023-09-23","text":"","title":"5.0.0-18(2023-09-23)"},{"location":"CHANGELOG/#features_2","text":"adding configuration and logs details ( d136f3d ) updating configuration docs ( a1933e3 )","title":"Features"},{"location":"CHANGELOG/#bug-fixes_3","text":"prepare for 5.0.0-18 release ( 29f822f ) prepare for 5.0.0-18 release ( 4af69cb ) versioning ( 1abf437 )","title":"Bug Fixes"},{"location":"CHANGELOG/#500-16-2023-08-14","text":"","title":"5.0.0-16 (2023-08-14)"},{"location":"CHANGELOG/#bug-fixes_4","text":"prepare for 5.0.0-16 release ( 699d534 )","title":"Bug Fixes"},{"location":"CHANGELOG/#500-15-2023-07-14","text":"","title":"5.0.0-15 (2023-07-14)"},{"location":"CHANGELOG/#features_3","text":"adding tags ( 7841e03 ) documentation of admin-ui #1063 ( 3cf1e7b ) documentation of admin-ui #1063 ( 48233d3 ) edit flex license contents ( 8d7f749 ) making changes as per review comments ( 1bcd39b ) making changes as per review comments ( 5c636fb )","title":"Features"},{"location":"CHANGELOG/#bug-fixes_5","text":"doc: added How to configure SuperGluu in Flex ( 6b7beef ) doc: adding SG screenshot - 2 ( e06bd79 ) doc: adding SG screenshot-1 ( b581a03 ) doc: enable SG - 2 ( d86ec85 ) doc: Flex SG doc review - How to Use SuperGluu ( f564dd1 ) doc: hiding ad removal related doc ( 5354e84 ) doc: how to enable SG in Flex-UI ( 4851205 ) doc: index page flex ( 7d48422 ) doc: removing key list from user record info ( 01b671a ) docs: flex-ui SG -- Compatability ( f78c46a ) doc: SG flex - How to use Super Gluu-1 ( e07641c ) doc: sg flex - how to use Super Gluu-screenshot location ( 7798023 ) doc: sg workflows ( 601b237 ) docs: test SG authentication ( 32f6b24 ) doc: test authentication SG ( 6d0f550 ) doc: Test authentication user guide ( a554646 ) doc: uploading modified screenshot ( 0e9e0cf ) prepare for 5.0.0-15 release ( 664553a )","title":"Bug Fixes"},{"location":"CHANGELOG/#500-14-2023-06-12","text":"","title":"5.0.0-14 (2023-06-12)"},{"location":"CHANGELOG/#bug-fixes_6","text":"prepare for 5.0.0-14 release ( 9481f55 )","title":"Bug Fixes"},{"location":"CHANGELOG/#500-13-2023-05-12","text":"","title":"5.0.0-13 (2023-05-12)"},{"location":"CHANGELOG/#bug-fixes_7","text":"admin-ui: add apply button ( d334103 ) blockUI converted to functional component ( 4b8e7bd ) email_2fa_core/install.bat has been removed; ( f27e461 ) prepare for 5.0.13 release ( 8578827 ) profile details is distorted when multiple roles assigned to the user ( e4603d8 ) revert prod webpack config of static & fonts files ( 96fa135 )","title":"Bug Fixes"},{"location":"CHANGELOG/#500-12-2023-04-18","text":"","title":"5.0.0-12 (2023-04-18)"},{"location":"CHANGELOG/#bug-fixes_8","text":"prepare for 5.0.12 release ( 994c985 )","title":"Bug Fixes"},{"location":"CHANGELOG/#500-11-2023-04-06","text":"","title":"5.0.0-11 (2023-04-06)"},{"location":"CHANGELOG/#bug-fixes_9","text":"prepare for 5.0.11 release ( d3cc35a )","title":"Bug Fixes"},{"location":"CHANGELOG/#500-10-2023-03-16","text":"","title":"5.0.0-10 (2023-03-16)"},{"location":"CHANGELOG/#bug-fixes_10","text":"add cn license enforcment to chart ( 55fb0c9 ) prepare for 5.0.10 release ( 1ffcbc7 )","title":"Bug Fixes"},{"location":"CHANGELOG/#500-9-2023-03-09","text":"","title":"5.0.0-9 (2023-03-09)"},{"location":"CHANGELOG/#bug-fixes_11","text":"docs: ubuntu install download location ( bb3a5cd ) prepare for 5.0.0-9 release ( 716d309 )","title":"Bug Fixes"},{"location":"CHANGELOG/#500-8-2023-03-02","text":"","title":"5.0.0-8 (2023-03-02)"},{"location":"CHANGELOG/#bug-fixes_12","text":"prepare for 5.0.0-8 release ( 29e0cbb )","title":"Bug Fixes"},{"location":"CHANGELOG/#500-7-2023-02-22","text":"","title":"5.0.0-7 (2023-02-22)"},{"location":"CHANGELOG/#bug-fixes_13","text":"prepare for 5.0.0-7 release ( 7f96937 )","title":"Bug Fixes"},{"location":"CHANGELOG/#500-4-2022-12-08","text":"","title":"5.0.0-4 (2022-12-08)"},{"location":"CHANGELOG/#bug-fixes_14","text":"getting ready for a release ( a0de091 )","title":"Bug Fixes"},{"location":"CHANGELOG/#500-3-2022-11-08","text":"","title":"5.0.0-3 (2022-11-08)"},{"location":"CHANGELOG/#features_4","text":"admin-ui: reviewed previously updated dependencies #416 ( ab81760 )","title":"Features"},{"location":"CHANGELOG/#bug-fixes_15","text":"getting ready to release 5.0.0-3 ( e8f3ecc )","title":"Bug Fixes"},{"location":"CHANGELOG/#miscellaneous-chores","text":"release 5.0.0-2 ( 06c6e64 )","title":"Miscellaneous Chores"},{"location":"admin/","text":"Gluu Flex Admin Guide # Overview # Gluu Flex is a commercially supported distribution of the Janssen Project , including the OpenID, OAuth, Config, FIDO, Casa, and SCIM Server components. Additionally, Flex includes the commercially licensed Flex Admin UI. Janssen Documentation # Central to Gluu Flex is the Janssen Project . Janssen enables organizations to build a scalable centralized authentication and authorization service using free open source software. Admin UI # The Gluu Flex Admin UI is a reactive web interface to simplify the management and configuration of your Auth Server. The Admin UI enables you to easily view and edit configuration properties, interception scripts, clients, and metrics in one place.","title":"Gluu Flex Admin Guide"},{"location":"admin/#gluu-flex-admin-guide","text":"","title":"Gluu Flex Admin Guide"},{"location":"admin/#overview","text":"Gluu Flex is a commercially supported distribution of the Janssen Project , including the OpenID, OAuth, Config, FIDO, Casa, and SCIM Server components. Additionally, Flex includes the commercially licensed Flex Admin UI.","title":"Overview"},{"location":"admin/#janssen-documentation","text":"Central to Gluu Flex is the Janssen Project . Janssen enables organizations to build a scalable centralized authentication and authorization service using free open source software.","title":"Janssen Documentation"},{"location":"admin/#admin-ui","text":"The Gluu Flex Admin UI is a reactive web interface to simplify the management and configuration of your Auth Server. The Admin UI enables you to easily view and edit configuration properties, interception scripts, clients, and metrics in one place.","title":"Admin UI"},{"location":"admin/config/","text":"Configuring Gluu Flex # Overview # After installing, there are four primary strategies to configure Gluu Flex. Text-based User Interface (TUI) # The current recommendation is to use the Janssen TUI to configure Flex components. The TUI calls the Config API to perform ad hoc configuration, and instructions can be found in the Janssen documentation here. CURL Commands # As an alternative, the Config API can be called directly using CURL commands. Command Line Interface (CLI) # If needed, a command-line alternative to the TUI is available. Instructions can be found in the Janssen documentation here. Admin UI # The Gluu Flex Admin UI is a reactive web interface to simplify the management and configuration of your Auth Server. The Admin UI enables you to easily view and edit configuration properties, interception scripts, clients, and metrics in one place. The Admin UI can be accessed by accessing the hostname set during installation in the browser.","title":"Configuration"},{"location":"admin/config/#configuring-gluu-flex","text":"","title":"Configuring Gluu Flex"},{"location":"admin/config/#overview","text":"After installing, there are four primary strategies to configure Gluu Flex.","title":"Overview"},{"location":"admin/config/#text-based-user-interface-tui","text":"The current recommendation is to use the Janssen TUI to configure Flex components. The TUI calls the Config API to perform ad hoc configuration, and instructions can be found in the Janssen documentation here.","title":"Text-based User Interface (TUI)"},{"location":"admin/config/#curl-commands","text":"As an alternative, the Config API can be called directly using CURL commands.","title":"CURL Commands"},{"location":"admin/config/#command-line-interface-cli","text":"If needed, a command-line alternative to the TUI is available. Instructions can be found in the Janssen documentation here.","title":"Command Line Interface (CLI)"},{"location":"admin/config/#admin-ui","text":"The Gluu Flex Admin UI is a reactive web interface to simplify the management and configuration of your Auth Server. The Admin UI enables you to easily view and edit configuration properties, interception scripts, clients, and metrics in one place. The Admin UI can be accessed by accessing the hostname set during installation in the browser.","title":"Admin UI"},{"location":"admin/admin-ui/","text":"Where is this content? # The Gluu Flex documentation is a work in progress, and this document is currently a draft. Keep an eye on this page for updates.","title":"Index"},{"location":"admin/admin-ui/#where-is-this-content","text":"The Gluu Flex documentation is a work in progress, and this document is currently a draft. Keep an eye on this page for updates.","title":"Where is this content?"},{"location":"admin/admin-ui/admin-menu/","tags":["administration","admin-ui","admin","role","permission","scripts","mau"],"text":"Admin Menu # The features like managing Roles and Permissions, Custom Scripts and monthly active users monitoring are placed under the Admin menu (in the left navigation of GUI). These features will be discussed one by one in this section. GUI Access Control # The administrator can control view/edit/delete access of users of Gluu Flex Admin UI by adding or removing the appropriate Permissions mapped to the user's Admin UI Role. For e.g. if the read Permission of OIDC clients ( https://jans.io/oauth/config/clients.readonly ) is not mapped to the logged-in user's Role, the contents of the page showing OIDC client records will not be visible to the user. In the same way, if the write and delete Permissions of OIDC clients are not mapped then the user will not be able to edit or delete any OIDC client record. Role # The logged-in administrator can create, edit or delete Admin UI Roles using the Admin UI Roles Page. The Admin UI Role can be assigned to the user using the User Management feature of this GUI. After installation, the following Admin UI Roles can be seen on Admin UI: api-viewer, api-editor, api-manager and api-admin. The default user i.e. admin is assigned with api-admin role. A user with one or more Admin UI Role(s) assigned will be able to log into Gluu Flex Admin UI. Permissions (Scopes) # Gluu Flex Admin UI uses Config API to manage and configure the Jans Auth server. Config API helps in configuring auth-server, users, fido2 and scim modules. The APIs of this rest application are protected using an authorization token containing the appropriate permissions (scopes). The user interface has the capability to add, edit and delete the Permissions used to access the APIs (i.e. rest APIs used by Admin UI). Role-Permission Mapping # The administrator can map the Admin UI Role with one or more Permission(s) using the Role-Permission Mapping page. The Role mapped with Permissions can be then assigned to the user to allow access to the corresponding operations of the GUI. The below table lists the Permissions used in Admin UI: Permission Description https://jans.io/oauth/config/attributes.readonly View Person attributes https://jans.io/oauth/config/attributes.write Add/Edit Person attributes https://jans.io/oauth/config/attributes.delete Delete Person attributes https://jans.io/oauth/config/scopes.readonly View the Scopes https://jans.io/oauth/config/scopes.write Add/Edit Scopes https://jans.io/oauth/config/scopes.delete Delete Scopes https://jans.io/oauth/config/scripts.readonly View the Scripts https://jans.io/oauth/config/scripts.write Add/Edit Scripts https://jans.io/oauth/config/scripts.delete Delete Scripts https://jans.io/oauth/config/openid/clients.readonly View the Clients https://jans.io/oauth/config/openid/clients.write Add/Edit Clients https://jans.io/oauth/config/openid/clients.delete Delete Clients https://jans.io/oauth/config/smtp.readonly View SMTP configuration https://jans.io/oauth/config/smtp.write Edit SMTP configuration https://jans.io/oauth/config/smtp.delete Remove SMTP configuration https://jans.io/oauth/config/logging.readonly View Auth server log configuration https://jans.io/oauth/config/logging.write Edit Auth server log configuration https://jans.io/oauth/config/database/ldap.readonly View LDAP persistence configuration https://jans.io/oauth/config/database/ldap.write Edit LDAP persistence configuration https://jans.io/oauth/config/database/ldap.delete Delete LDAP persistence configuration https://jans.io/oauth/config/jwks.readonly View JWKS https://jans.io/oauth/jans-auth-server/config/adminui/user/role.readonly View Admin UI Roles https://jans.io/oauth/jans-auth-server/config/adminui/user/role.write Edit Admin UI Roles https://jans.io/oauth/jans-auth-server/config/adminui/user/role.delete Delete Admin UI Roles https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.readonly View Admin UI Permissions https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.write Edit Admin UI Permissions https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.delete Delete Admin UI Permissions https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.readonly View Role-Permission Mapping https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.write Edit Role-Permission Mapping https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.delete Delete Role-Permission Mapping Custom Scripts # Custom Scripts are used to implement custom business logic for authentication, authorization, client registration, cache refresh, scopes, token revocation etc. The Janssen Authentication Server leverages Custom Scripts when implemented can facilitate complex business workflows without changing the server code. Gluu Flex Admin UI provides the interface to add/edit/delete custom scripts. Custom Scripts fields descriptions # INUM: Unique id identifying the script. Name: Name of the custom script. Only letters, digits and underscores are allowed. Description: Description of the script. Select SAML ACRS: The SAML parameter Authentication Context Requests (ACRS). Script Type: The type of the script (e.g. PERSON_AUTHENTICATION, INTROSPECTION, APPLICATION_SESSION, CLIENT_REGISTRATION etc). Programming Language: Programming language of the custom script (e.g. Java and Jython). Location Type: The location of the script, either database or file. Level: The level describes how secure and reliable the script is. Custom properties (key/value): Custom properties that can be used in the script. Script: Script content. Enable: Field set to enable or disable the script. MAU Graph # This is a line graph showing month-wise active users under a selected date range. Webhooks # Webhooks can be created and mapped to various Admin UI features to execute custom business logic when events associated with those features occur. Follow this tutorial for more details. Settings # The Gluu Flex Admin UI provides a user-friendly interface for managing various UI settings of this web application. This page has the following fields. List paging size: This field allows to define the default paging size for all search pages within the Admin UI. Config API URL: The read-only URL of the Jans Config API is used by the Admin UI for interaction. Admin UI Session Timeout (In Minutes): This field determines the maximum idle time allowed before a user is automatically logged out of the Admin UI. Admin UI authentication method (ACR): This dropdown enables user to select the default authentication method to be used in the Admin UI. Custom Parameters (for authentication): The custom parameters allow you to pass additional information to the authorization server during Admin UI authentication.","title":"Admin"},{"location":"admin/admin-ui/admin-menu/#admin-menu","text":"The features like managing Roles and Permissions, Custom Scripts and monthly active users monitoring are placed under the Admin menu (in the left navigation of GUI). These features will be discussed one by one in this section.","title":"Admin Menu"},{"location":"admin/admin-ui/admin-menu/#gui-access-control","text":"The administrator can control view/edit/delete access of users of Gluu Flex Admin UI by adding or removing the appropriate Permissions mapped to the user's Admin UI Role. For e.g. if the read Permission of OIDC clients ( https://jans.io/oauth/config/clients.readonly ) is not mapped to the logged-in user's Role, the contents of the page showing OIDC client records will not be visible to the user. In the same way, if the write and delete Permissions of OIDC clients are not mapped then the user will not be able to edit or delete any OIDC client record.","title":"GUI Access Control"},{"location":"admin/admin-ui/admin-menu/#role","text":"The logged-in administrator can create, edit or delete Admin UI Roles using the Admin UI Roles Page. The Admin UI Role can be assigned to the user using the User Management feature of this GUI. After installation, the following Admin UI Roles can be seen on Admin UI: api-viewer, api-editor, api-manager and api-admin. The default user i.e. admin is assigned with api-admin role. A user with one or more Admin UI Role(s) assigned will be able to log into Gluu Flex Admin UI.","title":"Role"},{"location":"admin/admin-ui/admin-menu/#permissions-scopes","text":"Gluu Flex Admin UI uses Config API to manage and configure the Jans Auth server. Config API helps in configuring auth-server, users, fido2 and scim modules. The APIs of this rest application are protected using an authorization token containing the appropriate permissions (scopes). The user interface has the capability to add, edit and delete the Permissions used to access the APIs (i.e. rest APIs used by Admin UI).","title":"Permissions (Scopes)"},{"location":"admin/admin-ui/admin-menu/#role-permission-mapping","text":"The administrator can map the Admin UI Role with one or more Permission(s) using the Role-Permission Mapping page. The Role mapped with Permissions can be then assigned to the user to allow access to the corresponding operations of the GUI. The below table lists the Permissions used in Admin UI: Permission Description https://jans.io/oauth/config/attributes.readonly View Person attributes https://jans.io/oauth/config/attributes.write Add/Edit Person attributes https://jans.io/oauth/config/attributes.delete Delete Person attributes https://jans.io/oauth/config/scopes.readonly View the Scopes https://jans.io/oauth/config/scopes.write Add/Edit Scopes https://jans.io/oauth/config/scopes.delete Delete Scopes https://jans.io/oauth/config/scripts.readonly View the Scripts https://jans.io/oauth/config/scripts.write Add/Edit Scripts https://jans.io/oauth/config/scripts.delete Delete Scripts https://jans.io/oauth/config/openid/clients.readonly View the Clients https://jans.io/oauth/config/openid/clients.write Add/Edit Clients https://jans.io/oauth/config/openid/clients.delete Delete Clients https://jans.io/oauth/config/smtp.readonly View SMTP configuration https://jans.io/oauth/config/smtp.write Edit SMTP configuration https://jans.io/oauth/config/smtp.delete Remove SMTP configuration https://jans.io/oauth/config/logging.readonly View Auth server log configuration https://jans.io/oauth/config/logging.write Edit Auth server log configuration https://jans.io/oauth/config/database/ldap.readonly View LDAP persistence configuration https://jans.io/oauth/config/database/ldap.write Edit LDAP persistence configuration https://jans.io/oauth/config/database/ldap.delete Delete LDAP persistence configuration https://jans.io/oauth/config/jwks.readonly View JWKS https://jans.io/oauth/jans-auth-server/config/adminui/user/role.readonly View Admin UI Roles https://jans.io/oauth/jans-auth-server/config/adminui/user/role.write Edit Admin UI Roles https://jans.io/oauth/jans-auth-server/config/adminui/user/role.delete Delete Admin UI Roles https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.readonly View Admin UI Permissions https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.write Edit Admin UI Permissions https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.delete Delete Admin UI Permissions https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.readonly View Role-Permission Mapping https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.write Edit Role-Permission Mapping https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.delete Delete Role-Permission Mapping","title":"Role-Permission Mapping"},{"location":"admin/admin-ui/admin-menu/#custom-scripts","text":"Custom Scripts are used to implement custom business logic for authentication, authorization, client registration, cache refresh, scopes, token revocation etc. The Janssen Authentication Server leverages Custom Scripts when implemented can facilitate complex business workflows without changing the server code. Gluu Flex Admin UI provides the interface to add/edit/delete custom scripts.","title":"Custom Scripts"},{"location":"admin/admin-ui/admin-menu/#custom-scripts-fields-descriptions","text":"INUM: Unique id identifying the script. Name: Name of the custom script. Only letters, digits and underscores are allowed. Description: Description of the script. Select SAML ACRS: The SAML parameter Authentication Context Requests (ACRS). Script Type: The type of the script (e.g. PERSON_AUTHENTICATION, INTROSPECTION, APPLICATION_SESSION, CLIENT_REGISTRATION etc). Programming Language: Programming language of the custom script (e.g. Java and Jython). Location Type: The location of the script, either database or file. Level: The level describes how secure and reliable the script is. Custom properties (key/value): Custom properties that can be used in the script. Script: Script content. Enable: Field set to enable or disable the script.","title":"Custom Scripts fields descriptions"},{"location":"admin/admin-ui/admin-menu/#mau-graph","text":"This is a line graph showing month-wise active users under a selected date range.","title":"MAU Graph"},{"location":"admin/admin-ui/admin-menu/#webhooks","text":"Webhooks can be created and mapped to various Admin UI features to execute custom business logic when events associated with those features occur. Follow this tutorial for more details.","title":"Webhooks"},{"location":"admin/admin-ui/admin-menu/#settings","text":"The Gluu Flex Admin UI provides a user-friendly interface for managing various UI settings of this web application. This page has the following fields. List paging size: This field allows to define the default paging size for all search pages within the Admin UI. Config API URL: The read-only URL of the Jans Config API is used by the Admin UI for interaction. Admin UI Session Timeout (In Minutes): This field determines the maximum idle time allowed before a user is automatically logged out of the Admin UI. Admin UI authentication method (ACR): This dropdown enables user to select the default authentication method to be used in the Admin UI. Custom Parameters (for authentication): The custom parameters allow you to pass additional information to the authorization server during Admin UI authentication.","title":"Settings"},{"location":"admin/admin-ui/auth-server-interaction/","tags":["administration","admin-ui","interaction"],"text":"Interaction with Jans Auth Server # This user-friendly interface facilitates interaction with the Jans Auth Server through a REST API layer known as the Jans Config API . Here, we'll explore the working mechanism of the Gluu Flex Admin UI, focusing on its interaction with the Jans Auth Server and the key steps involved. When accessing the Gluu Flex Admin UI through a web browser, the following steps are involved: License Verification # The user accesses the Gluu Flex Admin UI frontend through a web browser. The frontend requests the Admin UI backend to retrieve Admin UI configuration from Janssen persistence. The Admin UI configuration includes OIDC client details for accessing the Auth Server, OIDC client details for accessing the Token Server, OIDC client details for accessing the License APIs, and license metadata. It's important to note that the Admin UI backend is implemented as a Jans Config API plugin . The frontend calls the Admin UI backend API ( /isConfigValid ) to validate the license configuration in persistence, essentially verifying the validity of the OIDC client used to access the License APIs. If it is not valid, the same API tries to register a new OIDC client using the SSA uploaded during installation. In case the SSA is invalid, the Admin UI shows a page to upload a new valid SSA. After ensuring the validity of the OIDC client, the Admin UI calls the Admin UI backend API (/isActive) to check if a valid license is present in the license configuration. The Admin UI backend then calls the SCAN API (/scan/license/isActive) to verify the validity of the license. If a valid license is not present, the frontend calls the backend API (/retrieve) to retrieve the license for the user via the SCAN API (/scan/license/retrieve). The license can only be retrieved from SCAN if the user has subscribed to the Admin UI license in Agama Lab. If the user has not already subscribed to a valid license in Agama Lab, the Admin UI displays a page to generate a 30-day trial license. The user cannot generate another trial license after expiry of a generated trial license and will need to subscribe to the Admin UI license in Agama Lab to access the user interface. After verification of valid license the frontend initiates the Authorization Code Flow by redirecting the user to the login page. sequenceDiagram title License Verification autonumber actor User User->>Browser: open Admin UI URL Browser->>Gluu Flex Admin UI: launch Admin UI Gluu Flex Admin UI->>Admin UI Backend: /config Admin UI Backend->>Gluu Flex Admin UI: Admin UI config Gluu Flex Admin UI->>Admin UI Backend: /license/isConfigValid Note over Gluu Flex Admin UI,Admin UI Backend: validate license OIDC client alt license client valid Admin UI Backend->>Gluu Flex Admin UI: true else license client invalid Admin UI Backend->>account.gluu.org: DCR using SSA alt DCR success account.gluu.org->>Admin UI Backend: client credentials Admin UI Backend->>Admin UI Backend: save client credentials in persistence Admin UI Backend->>Gluu Flex Admin UI: true else DCR fails Admin UI Backend->>Gluu Flex Admin UI: false Gluu Flex Admin UI->>Browser: Screen to Upload SSA end end Gluu Flex Admin UI->>Admin UI Backend: /license/isActive Note over Gluu Flex Admin UI,Admin UI Backend: validate license Admin UI Backend->>SCAN: /scan/license/isActive alt license active SCAN->>Admin UI Backend: true else license inactive / not present SCAN->>Admin UI Backend: false Admin UI Backend->>SCAN: /retrieve alt license subscribed SCAN->>Admin UI Backend: license else license not subscribed SCAN->>Admin UI Backend: false Admin UI Backend->>Gluu Flex Admin UI: false Gluu Flex Admin UI->>Browser: Screen to generate Trial license end end Admin UI Backend->>Gluu Flex Admin UI: login page The Authorization Code Flow # The frontend initiates the Authorization Code Flow by calling authorization url and redirecting the user to the login page of the Janssen authorization server for user authentication. Upon successful authentication, the authorization server sends an authorization code and a state to the frontend. The frontend verifies the state. The frontend utilizes the authorization code to first obtain an access token ( AT1 ) from the token endpoint of the authorization server. With AT1, the frontend requests the User-Info in JWT format ( UJWT ) from the authorization server by calling userInfo endpoint. The frontend stores the UJWT and its claims, including the user's role ( claim name is jansAdminUIRole ) and other relevant information, in the Redux store. sequenceDiagram title License Verification autonumber actor User Gluu Flex Admin UI->>Jans Auth Server: /authorize Jans Auth Server->>Gluu Flex Admin UI:code Gluu Flex Admin UI->>Jans Auth Server: /token Note right of Gluu Flex Admin UI: code as parameter Jans Auth Server->>Gluu Flex Admin UI: access_token Note right of Gluu Flex Admin UI: access_token as parameter Gluu Flex Admin UI->>Jans Auth Server: /userInfo Jans Auth Server->>Gluu Flex Admin UI: user-info (UJWT) Gluu Flex Admin UI->>Gluu Flex Admin UI: extract & store claims from UJWT API Protection and Scopes # To ensure security and access control, Gluu Flex Admin UI leverages API protection and scopes: The Jans Config API's endpoints are protected and can only be accessed using a token ( AT2 ) with the required scopes. To generate an AT2, the frontend requests the Token Server via the backend. The Token Server and Authorization Server can be the same or different. The Token Server employs an introspection script that validates the UJWT and refers to the role-scope mapping in the Token Server persistence. The introspection script validates the UJWT and includes the appropriate scopes in AT2 based on the user's role. The frontend receives AT2 and associated scopes from the backend. Features in the frontend are enabled or disabled based on the scopes provided in AT2. Refer this doc for GUI access control. sequenceDiagram title License Verification autonumber actor User Gluu Flex Admin UI->>Admin UI Backend: /api-protection-token?ujwt=... Admin UI Backend->>Jans Token Server: /token Jans Token Server->>Jans Token Server: Verify ujwt Jans Token Server->>Jans Token Server: Add scopes to token based on role (AT2) Jans Token Server->>Admin UI Backend: AT2 Admin UI Backend->>Gluu Flex Admin UI: AT2 Gluu Flex Admin UI->>Gluu Flex Admin UI:extracts scopes from AT2 Gluu Flex Admin UI->>Gluu Flex Admin UI: GUI access control based on scopes from AT2 Accessing Config-API Endpoints # To access config-api endpoints, the following steps are taken: The Admin UI frontend requests AT2 from the Token Server through the backend. Armed with AT2, the frontend sends a request to the desired Jans Config API endpoint. AT2 is included in the authorization header, along with other request parameters. At the Jans Config API, AT2 is validated, and the provided scopes are verified to ensure the necessary scope for the requested endpoint is present. If the above steps are successful, the requested data is fetched from the Jans Config API and forwarded to the frontend. sequenceDiagram title License Verification autonumber actor User Gluu Flex Admin UI->>Admin UI Backend: /api-protection-token?ujwt=... Admin UI Backend->>Jans Token Server: /token Jans Token Server->>Jans Token Server: Verify ujwt Jans Token Server->>Jans Token Server: Add scopes to token based on role (AT2) Jans Token Server->>Admin UI Backend: AT2 Admin UI Backend->>Gluu Flex Admin UI: AT2 Gluu Flex Admin UI->>Jans Config API: request API with AT2 Jans Config API<<->>Jans Token Server: introspect AT2 Jans Token Server->>Jans Config API: AT2 JSON Jans Config API->>Jans Config API: Enforcement: verify required scopes Jans Config API->>Jans Config API: validate params Jans Config API->>Jans Auth Server:call API with request params Jans Auth Server->>Jans Config API:response Jans Config API->>Gluu Flex Admin UI:response Conclusion # The Gluu Flex Admin UI simplifies the process of managing configuration and features of the Jans Auth Server through an intuitive graphical user interface. By following the Authorization Code Flow and leveraging API protection and scopes, the Gluu Flex Admin UI ensures secure and controlled interaction with the Jans Auth Server's REST API layer. This seamless interaction empowers administrators to efficiently manage the Jans Auth Server's settings while adhering to strict access controls and security protocols.","title":"Auth Server Interaction"},{"location":"admin/admin-ui/auth-server-interaction/#interaction-with-jans-auth-server","text":"This user-friendly interface facilitates interaction with the Jans Auth Server through a REST API layer known as the Jans Config API . Here, we'll explore the working mechanism of the Gluu Flex Admin UI, focusing on its interaction with the Jans Auth Server and the key steps involved. When accessing the Gluu Flex Admin UI through a web browser, the following steps are involved:","title":"Interaction with Jans Auth Server"},{"location":"admin/admin-ui/auth-server-interaction/#license-verification","text":"The user accesses the Gluu Flex Admin UI frontend through a web browser. The frontend requests the Admin UI backend to retrieve Admin UI configuration from Janssen persistence. The Admin UI configuration includes OIDC client details for accessing the Auth Server, OIDC client details for accessing the Token Server, OIDC client details for accessing the License APIs, and license metadata. It's important to note that the Admin UI backend is implemented as a Jans Config API plugin . The frontend calls the Admin UI backend API ( /isConfigValid ) to validate the license configuration in persistence, essentially verifying the validity of the OIDC client used to access the License APIs. If it is not valid, the same API tries to register a new OIDC client using the SSA uploaded during installation. In case the SSA is invalid, the Admin UI shows a page to upload a new valid SSA. After ensuring the validity of the OIDC client, the Admin UI calls the Admin UI backend API (/isActive) to check if a valid license is present in the license configuration. The Admin UI backend then calls the SCAN API (/scan/license/isActive) to verify the validity of the license. If a valid license is not present, the frontend calls the backend API (/retrieve) to retrieve the license for the user via the SCAN API (/scan/license/retrieve). The license can only be retrieved from SCAN if the user has subscribed to the Admin UI license in Agama Lab. If the user has not already subscribed to a valid license in Agama Lab, the Admin UI displays a page to generate a 30-day trial license. The user cannot generate another trial license after expiry of a generated trial license and will need to subscribe to the Admin UI license in Agama Lab to access the user interface. After verification of valid license the frontend initiates the Authorization Code Flow by redirecting the user to the login page. sequenceDiagram title License Verification autonumber actor User User->>Browser: open Admin UI URL Browser->>Gluu Flex Admin UI: launch Admin UI Gluu Flex Admin UI->>Admin UI Backend: /config Admin UI Backend->>Gluu Flex Admin UI: Admin UI config Gluu Flex Admin UI->>Admin UI Backend: /license/isConfigValid Note over Gluu Flex Admin UI,Admin UI Backend: validate license OIDC client alt license client valid Admin UI Backend->>Gluu Flex Admin UI: true else license client invalid Admin UI Backend->>account.gluu.org: DCR using SSA alt DCR success account.gluu.org->>Admin UI Backend: client credentials Admin UI Backend->>Admin UI Backend: save client credentials in persistence Admin UI Backend->>Gluu Flex Admin UI: true else DCR fails Admin UI Backend->>Gluu Flex Admin UI: false Gluu Flex Admin UI->>Browser: Screen to Upload SSA end end Gluu Flex Admin UI->>Admin UI Backend: /license/isActive Note over Gluu Flex Admin UI,Admin UI Backend: validate license Admin UI Backend->>SCAN: /scan/license/isActive alt license active SCAN->>Admin UI Backend: true else license inactive / not present SCAN->>Admin UI Backend: false Admin UI Backend->>SCAN: /retrieve alt license subscribed SCAN->>Admin UI Backend: license else license not subscribed SCAN->>Admin UI Backend: false Admin UI Backend->>Gluu Flex Admin UI: false Gluu Flex Admin UI->>Browser: Screen to generate Trial license end end Admin UI Backend->>Gluu Flex Admin UI: login page","title":"License Verification"},{"location":"admin/admin-ui/auth-server-interaction/#the-authorization-code-flow","text":"The frontend initiates the Authorization Code Flow by calling authorization url and redirecting the user to the login page of the Janssen authorization server for user authentication. Upon successful authentication, the authorization server sends an authorization code and a state to the frontend. The frontend verifies the state. The frontend utilizes the authorization code to first obtain an access token ( AT1 ) from the token endpoint of the authorization server. With AT1, the frontend requests the User-Info in JWT format ( UJWT ) from the authorization server by calling userInfo endpoint. The frontend stores the UJWT and its claims, including the user's role ( claim name is jansAdminUIRole ) and other relevant information, in the Redux store. sequenceDiagram title License Verification autonumber actor User Gluu Flex Admin UI->>Jans Auth Server: /authorize Jans Auth Server->>Gluu Flex Admin UI:code Gluu Flex Admin UI->>Jans Auth Server: /token Note right of Gluu Flex Admin UI: code as parameter Jans Auth Server->>Gluu Flex Admin UI: access_token Note right of Gluu Flex Admin UI: access_token as parameter Gluu Flex Admin UI->>Jans Auth Server: /userInfo Jans Auth Server->>Gluu Flex Admin UI: user-info (UJWT) Gluu Flex Admin UI->>Gluu Flex Admin UI: extract & store claims from UJWT","title":"The Authorization Code Flow"},{"location":"admin/admin-ui/auth-server-interaction/#api-protection-and-scopes","text":"To ensure security and access control, Gluu Flex Admin UI leverages API protection and scopes: The Jans Config API's endpoints are protected and can only be accessed using a token ( AT2 ) with the required scopes. To generate an AT2, the frontend requests the Token Server via the backend. The Token Server and Authorization Server can be the same or different. The Token Server employs an introspection script that validates the UJWT and refers to the role-scope mapping in the Token Server persistence. The introspection script validates the UJWT and includes the appropriate scopes in AT2 based on the user's role. The frontend receives AT2 and associated scopes from the backend. Features in the frontend are enabled or disabled based on the scopes provided in AT2. Refer this doc for GUI access control. sequenceDiagram title License Verification autonumber actor User Gluu Flex Admin UI->>Admin UI Backend: /api-protection-token?ujwt=... Admin UI Backend->>Jans Token Server: /token Jans Token Server->>Jans Token Server: Verify ujwt Jans Token Server->>Jans Token Server: Add scopes to token based on role (AT2) Jans Token Server->>Admin UI Backend: AT2 Admin UI Backend->>Gluu Flex Admin UI: AT2 Gluu Flex Admin UI->>Gluu Flex Admin UI:extracts scopes from AT2 Gluu Flex Admin UI->>Gluu Flex Admin UI: GUI access control based on scopes from AT2","title":"API Protection and Scopes"},{"location":"admin/admin-ui/auth-server-interaction/#accessing-config-api-endpoints","text":"To access config-api endpoints, the following steps are taken: The Admin UI frontend requests AT2 from the Token Server through the backend. Armed with AT2, the frontend sends a request to the desired Jans Config API endpoint. AT2 is included in the authorization header, along with other request parameters. At the Jans Config API, AT2 is validated, and the provided scopes are verified to ensure the necessary scope for the requested endpoint is present. If the above steps are successful, the requested data is fetched from the Jans Config API and forwarded to the frontend. sequenceDiagram title License Verification autonumber actor User Gluu Flex Admin UI->>Admin UI Backend: /api-protection-token?ujwt=... Admin UI Backend->>Jans Token Server: /token Jans Token Server->>Jans Token Server: Verify ujwt Jans Token Server->>Jans Token Server: Add scopes to token based on role (AT2) Jans Token Server->>Admin UI Backend: AT2 Admin UI Backend->>Gluu Flex Admin UI: AT2 Gluu Flex Admin UI->>Jans Config API: request API with AT2 Jans Config API<<->>Jans Token Server: introspect AT2 Jans Token Server->>Jans Config API: AT2 JSON Jans Config API->>Jans Config API: Enforcement: verify required scopes Jans Config API->>Jans Config API: validate params Jans Config API->>Jans Auth Server:call API with request params Jans Auth Server->>Jans Config API:response Jans Config API->>Gluu Flex Admin UI:response","title":"Accessing Config-API Endpoints"},{"location":"admin/admin-ui/auth-server-interaction/#conclusion","text":"The Gluu Flex Admin UI simplifies the process of managing configuration and features of the Jans Auth Server through an intuitive graphical user interface. By following the Authorization Code Flow and leveraging API protection and scopes, the Gluu Flex Admin UI ensures secure and controlled interaction with the Jans Auth Server's REST API layer. This seamless interaction empowers administrators to efficiently manage the Jans Auth Server's settings while adhering to strict access controls and security protocols.","title":"Conclusion"},{"location":"admin/admin-ui/auth-server-menu/","tags":["administration","admin-ui","auth server","sessions","configuration","keys","logging","clients","scopes"],"text":"Auth Server Menu # The Auth Server menu covers the following important sub-menus to configure and manage Auth server. Sessions Server configuration Keys Logging Clients Scopes Enabled Acrs Agama deployment Sessions # The Janssen Authentication Server stores user session data in persistence. This screen lists the active session details and the administrator can revoke the sessions of the selected user. Keys # The JSON Web Key Sets (JWKS) is a set of public keys that should be used to verify any JSON Web Token (JWT) issued by the authorization server. Auth Server Configuration Properties # The auth server configuration properties can be updated using GUI. Logging # Following AS configuration properties can be used to customize AS logging: Log level: Specify the log levels of loggers Log layout: Logging layout used for Jans Authorization Server loggers Enable HTTP Logging: Enable/disable the request/response logging filter. Disabled by default. Disable JDK Logger?: Choose whether to disable JDK loggers Enable Oauth Audit Logging?: enable OAuth Audit Logging Clients # The logged-in user with appropriate permissions can view, register, edit and delete OIDC clients on auth server using Gluu Flex Admin UI. The Client details are as follows: Client fields Description Client name Name of the Client to be presented to the End-User. Client secret Client Secret. The same Client Secret value MUST NOT be assigned to multiple Clients. Description Description of the client. Authn method token endpoint Requested Client Authentication method for the Token Endpoint. The options are client_secret_post, client_secret_basic, client_secret_jwt, private_key_jwt, and none. Subject type Subject type requested for responses to this Client. The subject_types_supported Discovery parameter contains a list of the supported subject_type values for this server. Valid types include pairwise and public. Sector Identifier URI URL using the https scheme to be used in calculating Pseudonymous Identifiers by the OP. The URL references a file with a single JSON array of redirect_uri values. Grants List of the OAuth 2.0 Grant Types that the Client is declaring that it will restrict itself to using. Response types List of the OAuth 2.0 response_type values that the Client is declaring that it will restrict itself to using. If omitted, the default is that the Client will use only the code Response Type. Active Specifies whether the client is enabled. Application type Kind of the application. The default, if omitted, is web. Redirect URIs List of Redirection URI values used by the Client. One of these registered Redirection URI values MUST exactly match the redirect_uri parameter value used in each Authorization Request Redirect Regex When this field is set then redirect-URI must match with regex. Scopes List of scopes granted to the client. Access token type Type of the access token (JWT or reference) generated by the client. Include claims in id_token The claims will be included in id_token if this field is enabled Add auth_time to id_token When enabled then the auth_time claim is required in id_token. Run Introspection Script Before AccessToken As Jwt Creation And Include Claims When this field is enabled then Introspection Script will run before access token generation. Token binding confirmation method for id_token Specifies the JWT Confirmation Method member name (e.g. tbh) that the Relying Party expects when receiving Token Bound ID Tokens. The presence of this parameter indicates that the Relying Party supports the Token Binding of ID Tokens. If omitted, the default is that the Relying Party does not support the Token Binding of ID Tokens. Access token additional audiences The client audiences. Access token lifetime The client-specific access-token expiration. Refresh token lifetime The client-specific refresh-token expiration. Default max authn age The default maximum authentication age. Front channel. logout URI Relying Party (RP) URL that will cause the RP to log itself out when rendered in an iframe by the OP. This is used in the front-channel logout mechanisms, which communicate logout requests from the OP to RPs via the User Agent. Post logout redirect URI Provide the URLs supplied by the RP to request that the user be redirected to this location after a logout has been performed. Back channel. logout URI Relying Party (RP) URL that will cause the RP to log itself out when sent a Logout Token by the OP. This is used in the back-channel logout mechanisms, which communicate logout requests directly between the OP and RPs. Back channel. logout session required Boolean value specifying whether the RP requires that a sid (session ID) Claim be included in the Logout Token to identify the RP session with the OP when the backchannel_logout_uri is used. Front channel. logout session required Boolean value specifying whether the RP requires that iss (issuer) and sid (session ID) query parameters be included to identify the RP session with the OP when the frontchannel_logout_uri is used. Client URI URL of the home page of the Client. The value of this field must point to a valid Web page. Policy URI URL that the Relying Party Client provides to the End-User to read about how the profile data will be used. Logo URI URL that references a logo for the Client application. Terms of service URI URL that the Relying Party Client provides to the End-User to read about the Relying Party's terms of service. Contacts OpenID connect client contacts list. Authorized JS origins Specifies authorized JavaScript origins. Software id Specifies a unique identifier string (UUID) assigned by the client developer or software publisher used by registration endpoints to identify the client software to be dynamically registered. Software version Specifies a version identifier string for the client software identified by 'software_id'. The value of the 'software_version' should change on any update to the client software identified by the same 'software_id'. Software statement Specifies a software statement containing client metadata values about the client software as claims. This is a string value containing the entire signed JWT. CIBA: Token delivery method Specifies how backchannel token will be delivered. CIBA: Client notification endpoint Client Initiated Backchannel Authentication (CIBA) enables a Client to initiate the authentication of an end-user by means of out-of-band mechanisms. Upon receipt of the notification, the Client makes a request to the token endpoint to obtain the tokens. CIBA: Require user code param If selected the auth_time claim is included in id_token. PAR: Require lifetime Represents the lifetime of Pushed Authorisation Request (PAR). PAR: Require PAR Is Pushed Authorisation Request (PAR) required? UMA: RPT token type Type of RPT token (JWT or reference). UMA: Claims redirect URI Array of The Claims Redirect URIs to which the client wishes the authorization server to direct the requesting party's user agent after completing its interaction. UMA: RPT Modification Script List of Requesting Party Token (RPT) claims scripts. Client JWKS URI URL for the Client's JSON Web Key Set (JWK) document containing the key(s) that are used for signing requests to the OP. The JWK Set may also contain the Client''s encryption keys(s) that are used by the OP to encrypt the responses to the Client. When both signing and encryption keys are made available, a use (Key Use) parameter value is required for all keys in the document to indicate each key's intended usage. Client JWKS List of JSON Web Key (JWK) - A JSON object that represents a cryptographic key. The members of the object represent properties of the key, including its value. id_token subject type The subject identifiers in ID tokens. Persist Authorizations Specifies if the client authorization details are to be persisted. The default value is true. Allow spontaneous scopes Whether to allow spontaneous scopes for the client. Spontaneous scope validation regex List of spontaneous scope regular expression. Spontaneous scopes Spontaneous scopes created using the client. Initiate Login URI Specifies the URI using the https scheme that the authorization server can call to initiate a login at the client. Request URIs Provide a list of requests_uri values that are pre-registered by the Client for use at the Authorization Server. Default ACR Array of default requested Authentication Context Class Reference values that the Authorization Server must use for processing requests from the Client. Allowed ACRs Allowed ACRs Default prompt=login If enabled then sets prompt=login to the authorization request, which causes the authorization server to force the user to sign in again before it will show the authorization prompt. TLS Subject DN String representation of the expected subject distinguished name of the certificate, which the OAuth client will use in mutual TLS authentication. Is Expirable Client? Specifies whether client is expirable Client Scripts The custom scripts specific to the client. Scopes # The scope is a mechanism to limit an application's access to a user's account. An application can request one or more scopes, this information is then presented to the user in the consent screen, and the access token issued to the application will be limited to the scopes granted. Please check here for detail documentation on scopes. OAuth 2.0 scopes # This scope type would only have a description, but no claims. Once a client obtains this token, it may be passed to the backend API. OpenID scopes # Specify what access privileges are being requested for Access Tokens. The scopes associated with Access Tokens determine what resources will be available when they are used to access OAuth 2.0 protected endpoints. For OpenID Connect, scopes can be used to request that specific sets of information be made available as Claim Values. Spontaneous scopes # Spontaneous scopes are scopes with random part in it which are not known in advance. For e.g. transaction:4685456787, pis-552fds where 4685456787 or 552fds are generated part of the scope. Spontaneous scopes are disabled by default and can be enabled per client. The admins cannot create a spontaneous scope. Creation only happens when an authorized client presents a spontaneous scope at the token endpoint. There are the following client properties available during dynamic registration of the client related to spontaneous scopes: allowSpontaneousScopes OPTIONAL, boolean, false by default. Whether spontaneous scopes are allowed for the given client. spontaneousScopes OPTIONAL, array of strings. Regular expressions which should match to scope. If matched scope is allowed. Example: [\"^transaction:.+$\"]. It matches transaction:245 but not transaction:. UMA scopes # UMA scope can either be created by the user or auto-created by the authentication server. UMA scope cannot be modified using Gluu Flex Admin UI. If the logged-in user creates UMA scope then the creator type will be USER and the creator Id will be logged-in user's INUM. If auth server has auto-created a UMA scope then it will have the creator type as AUTO and no creator Id. Dynamic Scopes # The dynamic scope custom script allows to generate a list of claims (and their values) on the fly, depending on circumstances like the id of the client requesting it, logged user's session parameters, values of other user's attributes, results of some calculations implementing specific business logic and/or requests to remote APIs or databases. Claims are then returned the usual way in response to a call to the user info endpoint. In order to configure a dynamic scope the following steps are required: The script of type DYNAMIC_SCOPE must be configured and enabled. Create scope of scope type Dynamic and select Dynamic scope script and claims inputs. Authn # Authentication Context Class Reference (ACR) enables applications to request and verify the level of authentication assurance or the context of the authentication process used for user authentication. This page allows the administrator to view all enabled ACRs and select the default ACR which refers to the predefined or default authentication assurance when no specific ACR value is requested or specified. Agama # This menu addresses deployment of Agama project packages (file with .gama extension). To make sure that package is untempered, the file containing sha256 checksum also need to be uploaded on UI. The project name, description, version, deployment start/end date-time and deployment error (if any) can be seen on details popup of the record. User can export sample and current configuration or import configuration.","title":"Auth server"},{"location":"admin/admin-ui/auth-server-menu/#auth-server-menu","text":"The Auth Server menu covers the following important sub-menus to configure and manage Auth server. Sessions Server configuration Keys Logging Clients Scopes Enabled Acrs Agama deployment","title":"Auth Server Menu"},{"location":"admin/admin-ui/auth-server-menu/#sessions","text":"The Janssen Authentication Server stores user session data in persistence. This screen lists the active session details and the administrator can revoke the sessions of the selected user.","title":"Sessions"},{"location":"admin/admin-ui/auth-server-menu/#keys","text":"The JSON Web Key Sets (JWKS) is a set of public keys that should be used to verify any JSON Web Token (JWT) issued by the authorization server.","title":"Keys"},{"location":"admin/admin-ui/auth-server-menu/#auth-server-configuration-properties","text":"The auth server configuration properties can be updated using GUI.","title":"Auth Server Configuration Properties"},{"location":"admin/admin-ui/auth-server-menu/#logging","text":"Following AS configuration properties can be used to customize AS logging: Log level: Specify the log levels of loggers Log layout: Logging layout used for Jans Authorization Server loggers Enable HTTP Logging: Enable/disable the request/response logging filter. Disabled by default. Disable JDK Logger?: Choose whether to disable JDK loggers Enable Oauth Audit Logging?: enable OAuth Audit Logging","title":"Logging"},{"location":"admin/admin-ui/auth-server-menu/#clients","text":"The logged-in user with appropriate permissions can view, register, edit and delete OIDC clients on auth server using Gluu Flex Admin UI. The Client details are as follows: Client fields Description Client name Name of the Client to be presented to the End-User. Client secret Client Secret. The same Client Secret value MUST NOT be assigned to multiple Clients. Description Description of the client. Authn method token endpoint Requested Client Authentication method for the Token Endpoint. The options are client_secret_post, client_secret_basic, client_secret_jwt, private_key_jwt, and none. Subject type Subject type requested for responses to this Client. The subject_types_supported Discovery parameter contains a list of the supported subject_type values for this server. Valid types include pairwise and public. Sector Identifier URI URL using the https scheme to be used in calculating Pseudonymous Identifiers by the OP. The URL references a file with a single JSON array of redirect_uri values. Grants List of the OAuth 2.0 Grant Types that the Client is declaring that it will restrict itself to using. Response types List of the OAuth 2.0 response_type values that the Client is declaring that it will restrict itself to using. If omitted, the default is that the Client will use only the code Response Type. Active Specifies whether the client is enabled. Application type Kind of the application. The default, if omitted, is web. Redirect URIs List of Redirection URI values used by the Client. One of these registered Redirection URI values MUST exactly match the redirect_uri parameter value used in each Authorization Request Redirect Regex When this field is set then redirect-URI must match with regex. Scopes List of scopes granted to the client. Access token type Type of the access token (JWT or reference) generated by the client. Include claims in id_token The claims will be included in id_token if this field is enabled Add auth_time to id_token When enabled then the auth_time claim is required in id_token. Run Introspection Script Before AccessToken As Jwt Creation And Include Claims When this field is enabled then Introspection Script will run before access token generation. Token binding confirmation method for id_token Specifies the JWT Confirmation Method member name (e.g. tbh) that the Relying Party expects when receiving Token Bound ID Tokens. The presence of this parameter indicates that the Relying Party supports the Token Binding of ID Tokens. If omitted, the default is that the Relying Party does not support the Token Binding of ID Tokens. Access token additional audiences The client audiences. Access token lifetime The client-specific access-token expiration. Refresh token lifetime The client-specific refresh-token expiration. Default max authn age The default maximum authentication age. Front channel. logout URI Relying Party (RP) URL that will cause the RP to log itself out when rendered in an iframe by the OP. This is used in the front-channel logout mechanisms, which communicate logout requests from the OP to RPs via the User Agent. Post logout redirect URI Provide the URLs supplied by the RP to request that the user be redirected to this location after a logout has been performed. Back channel. logout URI Relying Party (RP) URL that will cause the RP to log itself out when sent a Logout Token by the OP. This is used in the back-channel logout mechanisms, which communicate logout requests directly between the OP and RPs. Back channel. logout session required Boolean value specifying whether the RP requires that a sid (session ID) Claim be included in the Logout Token to identify the RP session with the OP when the backchannel_logout_uri is used. Front channel. logout session required Boolean value specifying whether the RP requires that iss (issuer) and sid (session ID) query parameters be included to identify the RP session with the OP when the frontchannel_logout_uri is used. Client URI URL of the home page of the Client. The value of this field must point to a valid Web page. Policy URI URL that the Relying Party Client provides to the End-User to read about how the profile data will be used. Logo URI URL that references a logo for the Client application. Terms of service URI URL that the Relying Party Client provides to the End-User to read about the Relying Party's terms of service. Contacts OpenID connect client contacts list. Authorized JS origins Specifies authorized JavaScript origins. Software id Specifies a unique identifier string (UUID) assigned by the client developer or software publisher used by registration endpoints to identify the client software to be dynamically registered. Software version Specifies a version identifier string for the client software identified by 'software_id'. The value of the 'software_version' should change on any update to the client software identified by the same 'software_id'. Software statement Specifies a software statement containing client metadata values about the client software as claims. This is a string value containing the entire signed JWT. CIBA: Token delivery method Specifies how backchannel token will be delivered. CIBA: Client notification endpoint Client Initiated Backchannel Authentication (CIBA) enables a Client to initiate the authentication of an end-user by means of out-of-band mechanisms. Upon receipt of the notification, the Client makes a request to the token endpoint to obtain the tokens. CIBA: Require user code param If selected the auth_time claim is included in id_token. PAR: Require lifetime Represents the lifetime of Pushed Authorisation Request (PAR). PAR: Require PAR Is Pushed Authorisation Request (PAR) required? UMA: RPT token type Type of RPT token (JWT or reference). UMA: Claims redirect URI Array of The Claims Redirect URIs to which the client wishes the authorization server to direct the requesting party's user agent after completing its interaction. UMA: RPT Modification Script List of Requesting Party Token (RPT) claims scripts. Client JWKS URI URL for the Client's JSON Web Key Set (JWK) document containing the key(s) that are used for signing requests to the OP. The JWK Set may also contain the Client''s encryption keys(s) that are used by the OP to encrypt the responses to the Client. When both signing and encryption keys are made available, a use (Key Use) parameter value is required for all keys in the document to indicate each key's intended usage. Client JWKS List of JSON Web Key (JWK) - A JSON object that represents a cryptographic key. The members of the object represent properties of the key, including its value. id_token subject type The subject identifiers in ID tokens. Persist Authorizations Specifies if the client authorization details are to be persisted. The default value is true. Allow spontaneous scopes Whether to allow spontaneous scopes for the client. Spontaneous scope validation regex List of spontaneous scope regular expression. Spontaneous scopes Spontaneous scopes created using the client. Initiate Login URI Specifies the URI using the https scheme that the authorization server can call to initiate a login at the client. Request URIs Provide a list of requests_uri values that are pre-registered by the Client for use at the Authorization Server. Default ACR Array of default requested Authentication Context Class Reference values that the Authorization Server must use for processing requests from the Client. Allowed ACRs Allowed ACRs Default prompt=login If enabled then sets prompt=login to the authorization request, which causes the authorization server to force the user to sign in again before it will show the authorization prompt. TLS Subject DN String representation of the expected subject distinguished name of the certificate, which the OAuth client will use in mutual TLS authentication. Is Expirable Client? Specifies whether client is expirable Client Scripts The custom scripts specific to the client.","title":"Clients"},{"location":"admin/admin-ui/auth-server-menu/#scopes","text":"The scope is a mechanism to limit an application's access to a user's account. An application can request one or more scopes, this information is then presented to the user in the consent screen, and the access token issued to the application will be limited to the scopes granted. Please check here for detail documentation on scopes.","title":"Scopes"},{"location":"admin/admin-ui/auth-server-menu/#oauth-20-scopes","text":"This scope type would only have a description, but no claims. Once a client obtains this token, it may be passed to the backend API.","title":"OAuth 2.0 scopes"},{"location":"admin/admin-ui/auth-server-menu/#openid-scopes","text":"Specify what access privileges are being requested for Access Tokens. The scopes associated with Access Tokens determine what resources will be available when they are used to access OAuth 2.0 protected endpoints. For OpenID Connect, scopes can be used to request that specific sets of information be made available as Claim Values.","title":"OpenID scopes"},{"location":"admin/admin-ui/auth-server-menu/#spontaneous-scopes","text":"Spontaneous scopes are scopes with random part in it which are not known in advance. For e.g. transaction:4685456787, pis-552fds where 4685456787 or 552fds are generated part of the scope. Spontaneous scopes are disabled by default and can be enabled per client. The admins cannot create a spontaneous scope. Creation only happens when an authorized client presents a spontaneous scope at the token endpoint. There are the following client properties available during dynamic registration of the client related to spontaneous scopes: allowSpontaneousScopes OPTIONAL, boolean, false by default. Whether spontaneous scopes are allowed for the given client. spontaneousScopes OPTIONAL, array of strings. Regular expressions which should match to scope. If matched scope is allowed. Example: [\"^transaction:.+$\"]. It matches transaction:245 but not transaction:.","title":"Spontaneous scopes"},{"location":"admin/admin-ui/auth-server-menu/#uma-scopes","text":"UMA scope can either be created by the user or auto-created by the authentication server. UMA scope cannot be modified using Gluu Flex Admin UI. If the logged-in user creates UMA scope then the creator type will be USER and the creator Id will be logged-in user's INUM. If auth server has auto-created a UMA scope then it will have the creator type as AUTO and no creator Id.","title":"UMA scopes"},{"location":"admin/admin-ui/auth-server-menu/#dynamic-scopes","text":"The dynamic scope custom script allows to generate a list of claims (and their values) on the fly, depending on circumstances like the id of the client requesting it, logged user's session parameters, values of other user's attributes, results of some calculations implementing specific business logic and/or requests to remote APIs or databases. Claims are then returned the usual way in response to a call to the user info endpoint. In order to configure a dynamic scope the following steps are required: The script of type DYNAMIC_SCOPE must be configured and enabled. Create scope of scope type Dynamic and select Dynamic scope script and claims inputs.","title":"Dynamic Scopes"},{"location":"admin/admin-ui/auth-server-menu/#authn","text":"Authentication Context Class Reference (ACR) enables applications to request and verify the level of authentication assurance or the context of the authentication process used for user authentication. This page allows the administrator to view all enabled ACRs and select the default ACR which refers to the predefined or default authentication assurance when no specific ACR value is requested or specified.","title":"Authn"},{"location":"admin/admin-ui/auth-server-menu/#agama","text":"This menu addresses deployment of Agama project packages (file with .gama extension). To make sure that package is untempered, the file containing sha256 checksum also need to be uploaded on UI. The project name, description, version, deployment start/end date-time and deployment error (if any) can be seen on details popup of the record. User can export sample and current configuration or import configuration.","title":"Agama"},{"location":"admin/admin-ui/configuration/","tags":["administration","admin-ui","configuration"],"text":"Configuration # This document outlines the configuration process for Gluu Flex Admin UI, with a focus on essential components stored in the Auth Server's persistence layer. These components include role-permission mapping, OIDC client details for accessing the Auth Server, OIDC client details for accessing the Token Server, OIDC client details for accessing the License APIs, and license metadata. Configuration Components # Role-Permission Mapping # Role-permission mapping defines which administrative roles are granted specific permissions within the Gluu Flex Admin UI. This mapping ensures that administrators can only access and modify functionalities relevant to their roles. The mapping is stored in json format with following attributes. Roles Attribute Name Description roles Array of all roles role Role name description Role description deletable If set to true then entire role-permission mapping with respect to the role can be deleted. Default value: false Permissions Attribute Name Description permissions Array of all available permissions permission Permission name description Permission description defaultPermissionInToken If set to true , it indicates that permission will need authentication and valid role during /token request to include in token Mapping Attribute Name Description rolePermissionMapping List of all role-permission mapping role Role name permission Array of all permission mapped to the role Sample role-permission mapping stored in persistence { \"roles\": [ { \"role\": \"sample-role\", \"description\": \"role description\", \"deletable\": false } ], \"permissions\": [ { \"permission\": \"sample-permission1\", \"description\": \"permission1 description\", \"defaultPermissionInToken\": false }, { \"permission\": \"sample-permission2\", \"description\": \"permission2 description\", \"defaultPermissionInToken\": true } ], \"rolePermissionMapping\": [ { \"role\": \"sample-role\", \"permissions\": [ \"sample-permission1\", \"sample-permission2\" ] } ] } OIDC Client Details for Auth Server # To establish secure communication with the Auth Server, Gluu Flex Admin UI requires the OIDC client details, including client ID and client secret. These details are used for authentication and authorization purposes. The information is stored in json format with following attributes. Attribute Name Description auiWebClient Object with Web OIDC client details opHost Auth Server hostname clientId Client Id of OIDC client used to access Auth server clientSecret Client Secret of OIDC client used to access Auth server scopes Scopes required for Admin UI authentication acrValues ACR required for Admin UI authentication redirectUri Redirect UI which is Admin UI home page postLogoutUri Url to be redirected after Admin UI logout frontchannelLogoutUri Front channel Logout Uri additionalParameters The custom parameters allow you to pass additional information to the authorization server during Admin UI authentication. Format: [{\"key\": \"custom-param-key\", \"value\": \"custom-param-value\"}, ...] OIDC Client Details for Backend API Server # Similarly, Gluu Flex Admin UI needs OIDC client details to interact with the Janssen Server via. Jans Config API protected APIs. The Backend API client enables the UI to request and manage access tokens required to access Jans Config API protected resources. The information is stored in json format with following attributes. Attribute Name Description auiBackendApiClient Object with Backend API client details opHost Token Server hostname clientId Client Id of OIDC client used to access Token server clientSecret Client Secret of OIDC client used to access Token server tokenEndpoint Token endpoint of token server Configuration Properties for User-Interface # Attribute Name Description uiConfig Object with UI configuration attributes sessionTimeoutInMins The admin UI will auto-logout after a period of inactivity defined in this field. OIDC Client Details for License Server # Access to the License APIs is managed through OIDC client details. These details allows the Gluu Flex Admin UI Backend to generated access token to allow the retrieval of license-related information using license APIs. The information is stored in json format with following attributes. Attribute Name Description opHost Auth Server hostname used to generate token to access License APIs clientId Client Id of OIDC client used to generate token to access License APIs clientSecret Client Secret of OIDC client used to generate token to access License APIs License Metadata # License metadata includes relevant information about the Gluu Flex Admin UI's licensing, such as License Key, Hardware id, License server url, License Auth server url, SSA used to register license auth server client. The information is stored in json format with following attributes. Attribute Name Description licenseConfig Object with License configuration details ssa SSA used to register OIDC client to access license APIs scanLicenseApiHostname SCAN License server hostname licenseHardwareKey Hardware key (org_id) to access license APIs Sample configuration stored in persistence { \"oidcConfig\": { \"auiWebClient\": { \"redirectUri\": \"https://your.host.com/admin\", \"postLogoutUri\": \"https://your.gost.com/admin\", \"frontchannelLogoutUri\": \"https://your.host.com/admin/logout\", \"scopes\": [ \"openid\", \"profile\", \"user_name\", \"email\" ], \"acrValues\": [ \"basic\" ], \"opHost\": \"https://your.host.com\", \"clientId\": \"2001.aaf0b8eb-a82e-4798-b1a0-e007803a6568\", \"clientSecret\": \"GGO4t1uixrTpl4Rizt3zag==\". \"additionalParameters\": [] }, \"auiBackendApiClient\": { \"tokenEndpoint\": \"https://your.host.com/jans-auth/restv1/token\", \"scopes\": [ \"openid\", \"profile\", \"user_name\", \"email\" ], \"opHost\": \"https://your.host.com\", \"clientId\": \"2001.aaf0b8eb-a82e-4798-b1a0-e007803a6568\", \"clientSecret\": \"GGO4t1uixrTpl4Rizt3zag==\" } }, \"uiConfig\": { \"sessionTimeoutInMins\": 30 }, \"licenseConfig\": { \"ssa\": \"...ssa in jwt format...\", \"scanLicenseApiHostname\": \"https://cloud-dev.gluu.cloud\", \"licenseKey\": \"XXXX-XXXX-XXXX-XXXX\", \"licenseHardwareKey\": \"github:ghUsername\", \"oidcClient\": { \"opHost\": \"https://account-dev.gluu.cloud\", \"clientId\": \"36a43e2b-a77b-4e9c-a966-a9d98af1665c\", \"clientSecret\": \"211188d8-a2d8-4562-ab53-80907c1bb5ba\" } } }","title":"Configuration"},{"location":"admin/admin-ui/configuration/#configuration","text":"This document outlines the configuration process for Gluu Flex Admin UI, with a focus on essential components stored in the Auth Server's persistence layer. These components include role-permission mapping, OIDC client details for accessing the Auth Server, OIDC client details for accessing the Token Server, OIDC client details for accessing the License APIs, and license metadata.","title":"Configuration"},{"location":"admin/admin-ui/configuration/#configuration-components","text":"","title":"Configuration Components"},{"location":"admin/admin-ui/configuration/#role-permission-mapping","text":"Role-permission mapping defines which administrative roles are granted specific permissions within the Gluu Flex Admin UI. This mapping ensures that administrators can only access and modify functionalities relevant to their roles. The mapping is stored in json format with following attributes. Roles Attribute Name Description roles Array of all roles role Role name description Role description deletable If set to true then entire role-permission mapping with respect to the role can be deleted. Default value: false Permissions Attribute Name Description permissions Array of all available permissions permission Permission name description Permission description defaultPermissionInToken If set to true , it indicates that permission will need authentication and valid role during /token request to include in token Mapping Attribute Name Description rolePermissionMapping List of all role-permission mapping role Role name permission Array of all permission mapped to the role Sample role-permission mapping stored in persistence { \"roles\": [ { \"role\": \"sample-role\", \"description\": \"role description\", \"deletable\": false } ], \"permissions\": [ { \"permission\": \"sample-permission1\", \"description\": \"permission1 description\", \"defaultPermissionInToken\": false }, { \"permission\": \"sample-permission2\", \"description\": \"permission2 description\", \"defaultPermissionInToken\": true } ], \"rolePermissionMapping\": [ { \"role\": \"sample-role\", \"permissions\": [ \"sample-permission1\", \"sample-permission2\" ] } ] }","title":"Role-Permission Mapping"},{"location":"admin/admin-ui/configuration/#oidc-client-details-for-auth-server","text":"To establish secure communication with the Auth Server, Gluu Flex Admin UI requires the OIDC client details, including client ID and client secret. These details are used for authentication and authorization purposes. The information is stored in json format with following attributes. Attribute Name Description auiWebClient Object with Web OIDC client details opHost Auth Server hostname clientId Client Id of OIDC client used to access Auth server clientSecret Client Secret of OIDC client used to access Auth server scopes Scopes required for Admin UI authentication acrValues ACR required for Admin UI authentication redirectUri Redirect UI which is Admin UI home page postLogoutUri Url to be redirected after Admin UI logout frontchannelLogoutUri Front channel Logout Uri additionalParameters The custom parameters allow you to pass additional information to the authorization server during Admin UI authentication. Format: [{\"key\": \"custom-param-key\", \"value\": \"custom-param-value\"}, ...]","title":"OIDC Client Details for Auth Server"},{"location":"admin/admin-ui/configuration/#oidc-client-details-for-backend-api-server","text":"Similarly, Gluu Flex Admin UI needs OIDC client details to interact with the Janssen Server via. Jans Config API protected APIs. The Backend API client enables the UI to request and manage access tokens required to access Jans Config API protected resources. The information is stored in json format with following attributes. Attribute Name Description auiBackendApiClient Object with Backend API client details opHost Token Server hostname clientId Client Id of OIDC client used to access Token server clientSecret Client Secret of OIDC client used to access Token server tokenEndpoint Token endpoint of token server","title":"OIDC Client Details for Backend API Server"},{"location":"admin/admin-ui/configuration/#configuration-properties-for-user-interface","text":"Attribute Name Description uiConfig Object with UI configuration attributes sessionTimeoutInMins The admin UI will auto-logout after a period of inactivity defined in this field.","title":"Configuration Properties for User-Interface"},{"location":"admin/admin-ui/configuration/#oidc-client-details-for-license-server","text":"Access to the License APIs is managed through OIDC client details. These details allows the Gluu Flex Admin UI Backend to generated access token to allow the retrieval of license-related information using license APIs. The information is stored in json format with following attributes. Attribute Name Description opHost Auth Server hostname used to generate token to access License APIs clientId Client Id of OIDC client used to generate token to access License APIs clientSecret Client Secret of OIDC client used to generate token to access License APIs","title":"OIDC Client Details for License Server"},{"location":"admin/admin-ui/configuration/#license-metadata","text":"License metadata includes relevant information about the Gluu Flex Admin UI's licensing, such as License Key, Hardware id, License server url, License Auth server url, SSA used to register license auth server client. The information is stored in json format with following attributes. Attribute Name Description licenseConfig Object with License configuration details ssa SSA used to register OIDC client to access license APIs scanLicenseApiHostname SCAN License server hostname licenseHardwareKey Hardware key (org_id) to access license APIs Sample configuration stored in persistence { \"oidcConfig\": { \"auiWebClient\": { \"redirectUri\": \"https://your.host.com/admin\", \"postLogoutUri\": \"https://your.gost.com/admin\", \"frontchannelLogoutUri\": \"https://your.host.com/admin/logout\", \"scopes\": [ \"openid\", \"profile\", \"user_name\", \"email\" ], \"acrValues\": [ \"basic\" ], \"opHost\": \"https://your.host.com\", \"clientId\": \"2001.aaf0b8eb-a82e-4798-b1a0-e007803a6568\", \"clientSecret\": \"GGO4t1uixrTpl4Rizt3zag==\". \"additionalParameters\": [] }, \"auiBackendApiClient\": { \"tokenEndpoint\": \"https://your.host.com/jans-auth/restv1/token\", \"scopes\": [ \"openid\", \"profile\", \"user_name\", \"email\" ], \"opHost\": \"https://your.host.com\", \"clientId\": \"2001.aaf0b8eb-a82e-4798-b1a0-e007803a6568\", \"clientSecret\": \"GGO4t1uixrTpl4Rizt3zag==\" } }, \"uiConfig\": { \"sessionTimeoutInMins\": 30 }, \"licenseConfig\": { \"ssa\": \"...ssa in jwt format...\", \"scanLicenseApiHostname\": \"https://cloud-dev.gluu.cloud\", \"licenseKey\": \"XXXX-XXXX-XXXX-XXXX\", \"licenseHardwareKey\": \"github:ghUsername\", \"oidcClient\": { \"opHost\": \"https://account-dev.gluu.cloud\", \"clientId\": \"36a43e2b-a77b-4e9c-a966-a9d98af1665c\", \"clientSecret\": \"211188d8-a2d8-4562-ab53-80907c1bb5ba\" } } }","title":"License Metadata"},{"location":"admin/admin-ui/dashboard/","tags":["administration","admin-ui","dashboard"],"text":"Dashboard # After successful authentication, the administrator is taken to the dashboard. The dashboard brings an organized presentation of crucial details at one place adding to the convenience of users in tracking and analysis of auth server and other details. Dashboard fields descriptions # OIDC Clients Count: The count of OIDC clients created on auth server. Active Users Count: The count of active users on auth server. Token Issued Count: This figure is the sum of the access-tokens with grant-type client credentials and authorization code and id-token. OAuth server status: The health status of the auth server. For e.g. Running or Down . Database status: The health status of the persistence (e.g. PostgreSQL, MySQL, Google Spanner etc). License Details # Admin UI uses LicenseSpring platform for customer license management. Product Name: The name of the product created on the LicenseSpring platform. The license issued for Admin UI activation is created under this product. Check LicenseSpring docs for more details. License Type: The type of license issued. For e.g. Perpetual, Time Limited, Subscription and Consumption. Customer Email: To issue a license, we need to enter customer details like first name, last name, company, email and phone number in the LicenseSpring platform. This field displays the email of the customer of the license. Company Name: The company name of the registered product. License Status: The status of the license (e.g. active or inactive). Access Token Graph # The dashboard has a bar graph showing month-wise access-token with grant-type client credentials , authorization code and id_token generated from auth server. Localization and Theme selection # Admin UI supports localization. The default language is English. The other supported languages are French and Portuguese. A new preferred language can be selected from the top right corner of the dashboard which will convert the labels and tooltip to the selected language. The administrator can also select from four website themes in Admin UI.","title":"Home"},{"location":"admin/admin-ui/dashboard/#dashboard","text":"After successful authentication, the administrator is taken to the dashboard. The dashboard brings an organized presentation of crucial details at one place adding to the convenience of users in tracking and analysis of auth server and other details.","title":"Dashboard"},{"location":"admin/admin-ui/dashboard/#dashboard-fields-descriptions","text":"OIDC Clients Count: The count of OIDC clients created on auth server. Active Users Count: The count of active users on auth server. Token Issued Count: This figure is the sum of the access-tokens with grant-type client credentials and authorization code and id-token. OAuth server status: The health status of the auth server. For e.g. Running or Down . Database status: The health status of the persistence (e.g. PostgreSQL, MySQL, Google Spanner etc).","title":"Dashboard fields descriptions"},{"location":"admin/admin-ui/dashboard/#license-details","text":"Admin UI uses LicenseSpring platform for customer license management. Product Name: The name of the product created on the LicenseSpring platform. The license issued for Admin UI activation is created under this product. Check LicenseSpring docs for more details. License Type: The type of license issued. For e.g. Perpetual, Time Limited, Subscription and Consumption. Customer Email: To issue a license, we need to enter customer details like first name, last name, company, email and phone number in the LicenseSpring platform. This field displays the email of the customer of the license. Company Name: The company name of the registered product. License Status: The status of the license (e.g. active or inactive).","title":"License Details"},{"location":"admin/admin-ui/dashboard/#access-token-graph","text":"The dashboard has a bar graph showing month-wise access-token with grant-type client credentials , authorization code and id_token generated from auth server.","title":"Access Token Graph"},{"location":"admin/admin-ui/dashboard/#localization-and-theme-selection","text":"Admin UI supports localization. The default language is English. The other supported languages are French and Portuguese. A new preferred language can be selected from the top right corner of the dashboard which will convert the labels and tooltip to the selected language. The administrator can also select from four website themes in Admin UI.","title":"Localization and Theme selection"},{"location":"admin/admin-ui/faq/","text":"Frequently Asked Questions (FAQ) # Why is the Gluu Flex Admin UI displaying the following error messages after the Flex VM installation? # The requested page not found # Error Code: 404 The requested page was not found on this server. If a user encounters the above error when visiting the Admin UI URL, it indicates that the Admin UI is not properly installed. Please verify whether the Admin UI build is located at /var/www/html/admin . If the build is not present at this location, Janssen displays this error. Admin UI backend is down # Error Code: 503 Gluu Flex Admin UI is not getting any response from the backend (Jans Config Api). Gluu Flex Admin UI facilitates interaction with the Jans Auth Server through a REST API layer, Jans Config API . This error prompts administrators to perform a series of troubleshooting steps. Verify the status of the Jans Config API service by using the command systemctl status jans-config-api.service . In the majority of cases, this error is displayed when the Jans Config API is not running. It is essential to verify the server's network connectivity, including firewall rules, ports, and routing, to ensure that there are no network-related impediments preventing communication with the Jans Config API. Jans Config API runs at port 8074 for Janssen vm installation. Check the Jans Config API logs at /opt/jans/jetty/jans-config-api/logs/configapi.log for any potential errors. Review the Admin UI logs at /opt/jans/jetty/jans-config-api/logs/adminui.log to check for any potential errors. Confirm the existence of the /opt/jans/jetty/jans-config-api/custom/libs/gluu-flex-admin-ui-plugin.jar file. This file serves as the backend jar for the Admin UI and is used as a Jans Config API extension. It is also recommended to check the browser's console log and network tab for any failing requests, as this can provide additional information to diagnose and troubleshoot issues. Internal server error in generating Jans Config Api token # Error Code: 500 Error in generating token to access Jans Config Api endpoints. This error is displayed when there is an internal server error in generating an access token for the Jans Config API. The Jans Config API endpoints are protected and require a token with the appropriate scopes for access. Inspect the Gluu Flex Admin UI log at /opt/jans/jetty/jans-config-api/logs/adminui.log for any errors related to token requests. Examine the Janssen Auth server log at /opt/jans/jetty/jans-auth/logs/jans-auth.log while it is in debug/trace mode to identify any errors that may occur during token generation. Why is the Gluu Flex Admin UI is displaying following page to upload SSA? # During installation, it is necessary to provide a Software Statement Assertion (SSA), which the Admin UI utilizes to register an OIDC client for accessing license APIs. To obtain a new SSA or renew an existing one, please follow the steps outlined in the provided guide from the Agama Lab web interface. If the SSA used during the installation has expired or become invalidated, you will need to upload a fresh SSA to regain access to the Admin UI. Why is the Gluu Flex Admin UI is displaying following message on screen to generate trial license? # Payment Required. This message indicates that in order to enjoy long-term access to the Gluu Flex Admin UI, you will need to subscribe for a Admin UI license on the Agama Lab website. License validity period has expired. This message is displayed when a user attempts to generate a trial license (from the Admin UI) after the previously generated trial license has expired. Please note that the Admin UI 30-day trial license can only be generated once per Agama Lab user.","title":"FAQ & Troubleshooting"},{"location":"admin/admin-ui/faq/#frequently-asked-questions-faq","text":"","title":"Frequently Asked Questions (FAQ)"},{"location":"admin/admin-ui/faq/#why-is-the-gluu-flex-admin-ui-displaying-the-following-error-messages-after-the-flex-vm-installation","text":"","title":"Why is the Gluu Flex Admin UI displaying the following error messages after the Flex VM installation?"},{"location":"admin/admin-ui/faq/#the-requested-page-not-found","text":"Error Code: 404 The requested page was not found on this server. If a user encounters the above error when visiting the Admin UI URL, it indicates that the Admin UI is not properly installed. Please verify whether the Admin UI build is located at /var/www/html/admin . If the build is not present at this location, Janssen displays this error.","title":"The requested page not found"},{"location":"admin/admin-ui/faq/#admin-ui-backend-is-down","text":"Error Code: 503 Gluu Flex Admin UI is not getting any response from the backend (Jans Config Api). Gluu Flex Admin UI facilitates interaction with the Jans Auth Server through a REST API layer, Jans Config API . This error prompts administrators to perform a series of troubleshooting steps. Verify the status of the Jans Config API service by using the command systemctl status jans-config-api.service . In the majority of cases, this error is displayed when the Jans Config API is not running. It is essential to verify the server's network connectivity, including firewall rules, ports, and routing, to ensure that there are no network-related impediments preventing communication with the Jans Config API. Jans Config API runs at port 8074 for Janssen vm installation. Check the Jans Config API logs at /opt/jans/jetty/jans-config-api/logs/configapi.log for any potential errors. Review the Admin UI logs at /opt/jans/jetty/jans-config-api/logs/adminui.log to check for any potential errors. Confirm the existence of the /opt/jans/jetty/jans-config-api/custom/libs/gluu-flex-admin-ui-plugin.jar file. This file serves as the backend jar for the Admin UI and is used as a Jans Config API extension. It is also recommended to check the browser's console log and network tab for any failing requests, as this can provide additional information to diagnose and troubleshoot issues.","title":"Admin UI backend is down"},{"location":"admin/admin-ui/faq/#internal-server-error-in-generating-jans-config-api-token","text":"Error Code: 500 Error in generating token to access Jans Config Api endpoints. This error is displayed when there is an internal server error in generating an access token for the Jans Config API. The Jans Config API endpoints are protected and require a token with the appropriate scopes for access. Inspect the Gluu Flex Admin UI log at /opt/jans/jetty/jans-config-api/logs/adminui.log for any errors related to token requests. Examine the Janssen Auth server log at /opt/jans/jetty/jans-auth/logs/jans-auth.log while it is in debug/trace mode to identify any errors that may occur during token generation.","title":"Internal server error in generating Jans Config Api token"},{"location":"admin/admin-ui/faq/#why-is-the-gluu-flex-admin-ui-is-displaying-following-page-to-upload-ssa","text":"During installation, it is necessary to provide a Software Statement Assertion (SSA), which the Admin UI utilizes to register an OIDC client for accessing license APIs. To obtain a new SSA or renew an existing one, please follow the steps outlined in the provided guide from the Agama Lab web interface. If the SSA used during the installation has expired or become invalidated, you will need to upload a fresh SSA to regain access to the Admin UI.","title":"Why is the Gluu Flex Admin UI is displaying following page to upload SSA?"},{"location":"admin/admin-ui/faq/#why-is-the-gluu-flex-admin-ui-is-displaying-following-message-on-screen-to-generate-trial-license","text":"Payment Required. This message indicates that in order to enjoy long-term access to the Gluu Flex Admin UI, you will need to subscribe for a Admin UI license on the Agama Lab website. License validity period has expired. This message is displayed when a user attempts to generate a trial license (from the Admin UI) after the previously generated trial license has expired. Please note that the Admin UI 30-day trial license can only be generated once per Agama Lab user.","title":"Why is the Gluu Flex Admin UI is displaying following message on screen to generate trial license?"},{"location":"admin/admin-ui/fido-menu/","tags":["administration","admin-ui","fido2"],"text":"FIDO Configuration # FIDO 2.0 (FIDO2) is an open authentication standard that enables people to leverage common devices to authenticate to online services in both mobile and desktop environments. FIDO2 comprises the W3C\u2019s Web Authentication specification (WebAuthn) and FIDO\u2019s corresponding Client-to-Authenticator Protocol (CTAP). WebAuthn defines a standard web API that can be built into browsers and related web platform infrastructure to enable online services to use FIDO Authentication. CTAP enables external devices such as mobile handsets or FIDO Security Keys to work with WebAuthn and serve as authenticators to desktop applications and web services. Gluu Flex Admin UI allows configuring parameters of Janssen's FIDO2 server. Check following documnetation for details of FIDO2 configuration parameters.","title":"FIDO"},{"location":"admin/admin-ui/fido-menu/#fido-configuration","text":"FIDO 2.0 (FIDO2) is an open authentication standard that enables people to leverage common devices to authenticate to online services in both mobile and desktop environments. FIDO2 comprises the W3C\u2019s Web Authentication specification (WebAuthn) and FIDO\u2019s corresponding Client-to-Authenticator Protocol (CTAP). WebAuthn defines a standard web API that can be built into browsers and related web platform infrastructure to enable online services to use FIDO Authentication. CTAP enables external devices such as mobile handsets or FIDO Security Keys to work with WebAuthn and serve as authenticators to desktop applications and web services. Gluu Flex Admin UI allows configuring parameters of Janssen's FIDO2 server. Check following documnetation for details of FIDO2 configuration parameters.","title":"FIDO Configuration"},{"location":"admin/admin-ui/introduction/","tags":["administration","admin-ui","installation","license"],"text":"Gluu Flex Admin UI # Gluu Flex Admin UI is a web interface to simplify the management and configuration of your Janssen Authentication Server. One of the key services offered by Gluu Flex is the ability to view and edit configuration properties, interception scripts, clients, users, metrics, and more, all in one place. This user-friendly interface facilitates interaction with the Jans Auth Server through a REST API layer known as the Jans Config API. The above diagram explains interaction between various depending components. Admin UI Frontend # This user facing GUI has been developed using React.js and Redux is used for state management. The Admin UI utilizes an OpenAPI JavaScript client for Jans Config API, facilitating API calls to Jans Config API endpoints. The GUI utilizes popular libraries such as Material-UI , Axios, Formik , etc. Webpack is responsible for compiling and bundling the application, optimizing its performance, and generating the necessary production files. The Admin UI bundle is hosted on an Apache HTTP server , which is included as a component with the Janssen server installation. This setup ensures that the GUI is readily accessible and efficiently served to users. Admin UI Backend # The GUI utilizes a dedicated Java backend to handle specific tasks, such as reading the Admin UI configuration from persistence, managing Admin UI roles and permission mapping in configuration, performing audit logging, and making calls to license APIs on SCAN. The Jans Config API follows a flexible plugin architecture, allowing the addition of new APIs through extensions known as plugins, without the need to modify the core application. The Admin UI Backend has been incorporated into the Jans Config API as a plugin to address Admin UI-specific tasks. Installation # Gluu Flex can be installed using VM installer or using Rancher on Cloud Native. During installation, we need to provide a Software Statement Assertion (SSA) which is used by Admin UI to register an OIDC client to access license APIs. Check the following guide for the steps to issue SSA from the Agama Lab web interface. Gluu Flex License # After installation, the Admin UI can be accessed at https://hostname/admin (the hostname is provided during setup). Access to this web interface is granted only after subscribing to the Admin UI license from Agama Lab. There is a provision to generate a 30-day free trial license of Gluu Flex which will help users to enter and understand this web interface. After license activation, the user can log into Gluu Flex Admin UI using the default username ( admin ) and the password (the admin password provided during installation). Flex services dependencies # Gluu Flex Admin UI depends on following Flex services: Janssen Config API service (jans-config-api.service) The Apache HTTP Server (apache2.service)","title":"Introduction"},{"location":"admin/admin-ui/introduction/#gluu-flex-admin-ui","text":"Gluu Flex Admin UI is a web interface to simplify the management and configuration of your Janssen Authentication Server. One of the key services offered by Gluu Flex is the ability to view and edit configuration properties, interception scripts, clients, users, metrics, and more, all in one place. This user-friendly interface facilitates interaction with the Jans Auth Server through a REST API layer known as the Jans Config API. The above diagram explains interaction between various depending components.","title":"Gluu Flex Admin UI"},{"location":"admin/admin-ui/introduction/#admin-ui-frontend","text":"This user facing GUI has been developed using React.js and Redux is used for state management. The Admin UI utilizes an OpenAPI JavaScript client for Jans Config API, facilitating API calls to Jans Config API endpoints. The GUI utilizes popular libraries such as Material-UI , Axios, Formik , etc. Webpack is responsible for compiling and bundling the application, optimizing its performance, and generating the necessary production files. The Admin UI bundle is hosted on an Apache HTTP server , which is included as a component with the Janssen server installation. This setup ensures that the GUI is readily accessible and efficiently served to users.","title":"Admin UI Frontend"},{"location":"admin/admin-ui/introduction/#admin-ui-backend","text":"The GUI utilizes a dedicated Java backend to handle specific tasks, such as reading the Admin UI configuration from persistence, managing Admin UI roles and permission mapping in configuration, performing audit logging, and making calls to license APIs on SCAN. The Jans Config API follows a flexible plugin architecture, allowing the addition of new APIs through extensions known as plugins, without the need to modify the core application. The Admin UI Backend has been incorporated into the Jans Config API as a plugin to address Admin UI-specific tasks.","title":"Admin UI Backend"},{"location":"admin/admin-ui/introduction/#installation","text":"Gluu Flex can be installed using VM installer or using Rancher on Cloud Native. During installation, we need to provide a Software Statement Assertion (SSA) which is used by Admin UI to register an OIDC client to access license APIs. Check the following guide for the steps to issue SSA from the Agama Lab web interface.","title":"Installation"},{"location":"admin/admin-ui/introduction/#gluu-flex-license","text":"After installation, the Admin UI can be accessed at https://hostname/admin (the hostname is provided during setup). Access to this web interface is granted only after subscribing to the Admin UI license from Agama Lab. There is a provision to generate a 30-day free trial license of Gluu Flex which will help users to enter and understand this web interface. After license activation, the user can log into Gluu Flex Admin UI using the default username ( admin ) and the password (the admin password provided during installation).","title":"Gluu Flex License"},{"location":"admin/admin-ui/introduction/#flex-services-dependencies","text":"Gluu Flex Admin UI depends on following Flex services: Janssen Config API service (jans-config-api.service) The Apache HTTP Server (apache2.service)","title":"Flex services dependencies"},{"location":"admin/admin-ui/left-nav-menu/","tags":["administration","admin-ui","left navigation menu"],"text":"Left Navigation Menu # In the realm of web design and user experience, the left navigation menu holds a prominent position. It serves as a vital element in organizing and navigating the content within web applications. In Gluu Flex Admin UI the left navigation menu establishes a clear information hierarchy to access the core features. Gluu Flex Admin UI has the following main menus on the left navigation: Home Admin Auth server Schema Services SMTP Users Sign out","title":"Left Navigation Menu"},{"location":"admin/admin-ui/left-nav-menu/#left-navigation-menu","text":"In the realm of web design and user experience, the left navigation menu holds a prominent position. It serves as a vital element in organizing and navigating the content within web applications. In Gluu Flex Admin UI the left navigation menu establishes a clear information hierarchy to access the core features. Gluu Flex Admin UI has the following main menus on the left navigation: Home Admin Auth server Schema Services SMTP Users Sign out","title":"Left Navigation Menu"},{"location":"admin/admin-ui/logs/","tags":["administration","admin-ui","installation","logs"],"text":"Logs # Log files are essential components of a web application's infrastructure as they provide valuable insights into its functioning, performance, and potential issues. Log files play a critical role in maintaining, troubleshooting, and monitoring the Gluu Flex Admin UI application. Understanding the different log types, their locations, and the process of accessing and analyzing them will empower administrators to efficiently manage the application's health and quickly address any issues that may arise. Log File Types # The Gluu Flex Admin UI generates two types of log files: adminui.log : This is the backend log file that captures various activities, errors, and events related to the Gluu Flex Admin UI's operation. It provides insights into the application's behavior and potential issues. adminuiAudit.log : This audit log file records user interactions, actions, and events related to administrative activities. It's particularly useful for tracking changes made to the system and ensuring accountability. Configuration of Log Locations # The log locations for Gluu Flex Admin UI can be configured by modifying the log4j2-adminui.xml file located at: /opt/jans/jetty/jans-config-api/custom/config/log4j2-adminui.xml Within this configuration file, you can adjust various settings such as log levels, appenders, and formats. Default Log Location # The default log location for the Admin UI backend is: /var/log/adminui It is also recommended to check the browser's console log and network tab for any failing requests, as this can provide additional information to diagnose and troubleshoot issues.","title":"Logs"},{"location":"admin/admin-ui/logs/#logs","text":"Log files are essential components of a web application's infrastructure as they provide valuable insights into its functioning, performance, and potential issues. Log files play a critical role in maintaining, troubleshooting, and monitoring the Gluu Flex Admin UI application. Understanding the different log types, their locations, and the process of accessing and analyzing them will empower administrators to efficiently manage the application's health and quickly address any issues that may arise.","title":"Logs"},{"location":"admin/admin-ui/logs/#log-file-types","text":"The Gluu Flex Admin UI generates two types of log files: adminui.log : This is the backend log file that captures various activities, errors, and events related to the Gluu Flex Admin UI's operation. It provides insights into the application's behavior and potential issues. adminuiAudit.log : This audit log file records user interactions, actions, and events related to administrative activities. It's particularly useful for tracking changes made to the system and ensuring accountability.","title":"Log File Types"},{"location":"admin/admin-ui/logs/#configuration-of-log-locations","text":"The log locations for Gluu Flex Admin UI can be configured by modifying the log4j2-adminui.xml file located at: /opt/jans/jetty/jans-config-api/custom/config/log4j2-adminui.xml Within this configuration file, you can adjust various settings such as log levels, appenders, and formats.","title":"Configuration of Log Locations"},{"location":"admin/admin-ui/logs/#default-log-location","text":"The default log location for the Admin UI backend is: /var/log/adminui It is also recommended to check the browser's console log and network tab for any failing requests, as this can provide additional information to diagnose and troubleshoot issues.","title":"Default Log Location"},{"location":"admin/admin-ui/properties/","text":"Where is this content? # The Gluu Flex documentation is a work in progress, and this document is currently a draft. Keep an eye on this page for updates.","title":"Properties"},{"location":"admin/admin-ui/properties/#where-is-this-content","text":"The Gluu Flex documentation is a work in progress, and this document is currently a draft. Keep an eye on this page for updates.","title":"Where is this content?"},{"location":"admin/admin-ui/schema-menu/","tags":["administration","admin-ui","schema","person","attributes"],"text":"Schema # Attributes are individual pieces of user data, like uid or email, that are required by applications in order to identify a user and grant access to protected resources. The Person attributes that are available in your Janssen server can be found by navigating Schema > Person . The following fields are supported in the Person (attribute) creation form: Name: This field defines the name of the Person attribute. The name must be unique in the Janssen Server persistence tree. Display Name: The display name can be anything that is human-readable. Description: The description of the attribute. Status: Used to mark the attribute as Active so that it can be used in your federation service or choose Inactive to create the attribute that can be activated at a later date. Data Type: Select what type of attribute is being added in this field. Edit Type: This field controls who can edit this attribute. If user is selected, this will enable each user to edit this attribute in their Janssen server user profile. View Type: This field controls which type of user is allowed to view the corresponding attribute on the web user interface. oxAuth claim name: If this attribute will be used as a 'claim' in your OpenID Connect service, add the name of the claim here. Generally, the name of the attribute == name of the claim . Multivalued?: If the attribute contains more than one value, set this field to True. Hide On Discovery?: Boolean value indicating if the attribute should be shown on the discovery page. Include In SCIM Extension?: Boolean value indicating if the attribute is a SCIM custom attribute. Enable custom validation for this attribute?: If you plan to set minimum and maximum lengths or a regex pattern, as described below, you will need to enable custom validation for this attribute. Otherwise, you can leave this disabled. Regular expression: You can set a regex pattern to enforce the proper formatting of an attribute. For example, you could set a regex expression for an email attribute like this: ^[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,6}$. This would make sure that a value is added for the attribute only if it follows standard email formatting. Minimum length: This is the minimum length of a value associated with this attribute. Maximum length: This is the maximum length of a value associated with this attribute. Saml1 URI: This field can contain a SAML v1 supported nameformat for the new attribute. If this field is left blank the Janssen Server will automatically populate a value. Saml2 URI: This field can contain a SAML v2 supported nameformat for the new attribute. If this field is left blank the Janssen Server will automatically populate a value.","title":"Schema"},{"location":"admin/admin-ui/schema-menu/#schema","text":"Attributes are individual pieces of user data, like uid or email, that are required by applications in order to identify a user and grant access to protected resources. The Person attributes that are available in your Janssen server can be found by navigating Schema > Person . The following fields are supported in the Person (attribute) creation form: Name: This field defines the name of the Person attribute. The name must be unique in the Janssen Server persistence tree. Display Name: The display name can be anything that is human-readable. Description: The description of the attribute. Status: Used to mark the attribute as Active so that it can be used in your federation service or choose Inactive to create the attribute that can be activated at a later date. Data Type: Select what type of attribute is being added in this field. Edit Type: This field controls who can edit this attribute. If user is selected, this will enable each user to edit this attribute in their Janssen server user profile. View Type: This field controls which type of user is allowed to view the corresponding attribute on the web user interface. oxAuth claim name: If this attribute will be used as a 'claim' in your OpenID Connect service, add the name of the claim here. Generally, the name of the attribute == name of the claim . Multivalued?: If the attribute contains more than one value, set this field to True. Hide On Discovery?: Boolean value indicating if the attribute should be shown on the discovery page. Include In SCIM Extension?: Boolean value indicating if the attribute is a SCIM custom attribute. Enable custom validation for this attribute?: If you plan to set minimum and maximum lengths or a regex pattern, as described below, you will need to enable custom validation for this attribute. Otherwise, you can leave this disabled. Regular expression: You can set a regex pattern to enforce the proper formatting of an attribute. For example, you could set a regex expression for an email attribute like this: ^[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,6}$. This would make sure that a value is added for the attribute only if it follows standard email formatting. Minimum length: This is the minimum length of a value associated with this attribute. Maximum length: This is the maximum length of a value associated with this attribute. Saml1 URI: This field can contain a SAML v1 supported nameformat for the new attribute. If this field is left blank the Janssen Server will automatically populate a value. Saml2 URI: This field can contain a SAML v2 supported nameformat for the new attribute. If this field is left blank the Janssen Server will automatically populate a value.","title":"Schema"},{"location":"admin/admin-ui/services-menu/","tags":["administration","admin-ui","services","cache-configuration"],"text":"Services # This menu allows user to configure Cache Provider and LDAP schemas which can be used by the auth server. Cache Provider Configuration # The following cache providers are supported in Janssen's auth server: In Memory : recommended for small deployments only Memcached : recommended for single cache server deployment Redis : recommended for cluster deployments Native Persistence : recommended avoiding additional components' installation. All cache entries are saved in persistence layers. Cache Provider Properties # The following tables include the name and description of each Cache Provider's properties. Cache Configuration # Name Description Cache Provider Type The cache provider type Memcached Configuration # Name Description Server Details Server details separated by spaces (e.g. `server1:8080 server2:8081) Max Operation Queue Length Maximum number of operations that can be queued Buffer Size Buffer size in bytes Default Put Expiration Expiration timeout value in seconds Connection Factory Type Connection factory type In-Memory Configuration # Name Description Default Put Expiration Default put expiration timeout value in seconds Redis Configuration # Name Description Redis Provider Type Type of connection: standalone, clustered, sharded, sentinel Server Details Server details separated by commas (e.g. 'server1:8080,server2:8081') Use SSL Enable SSL communication between Gluu Server and Redis cache Password Redis password Sentinel Master Group Name Sentinel Master Group Name (required if SENTINEL type of connection is selected) SSL Trust Store File Path Directory Path to Trust Store Default Put Expiration Default expiration time for the object put into cache in seconds Max Retry Attempts Max retry attepts in case of failure So Timeout With this option set to a non-zero timeout, a read() call on the InputStream associated with this Socket will block for only this amount of time. If the timeout expires, a java.net.SocketTimeoutException is raised, though the Socket is still valid. The option must be enabled prior to entering the blocking operation to have effect. The timeout must be > 0. A timeout of zero is interpreted as an infinite timeout. Max Idle Connections The cap on the number of \\\"idle\\\" instances in the pool. If maxIdle is set too low on heavily loaded systems it is possible you will see objects being destroyed and almost immediately new objects being created. This is a result of the active threads momentarily returning objects faster than they are requesting them, causing the number of idle objects to rise above maxIdle. The best value for maxIdle for heavily loaded system will vary but the default is a good starting point. Max Total Connections The number of maximum connection instances in the pool Connection Timeout Connection time out Native Persistence Configuration # Name Description Default Put Expiration Default expiration time for the object put into cache in seconds Default Cleanup Batch Size Default cleanup batch page size Delete Expired OnGetRequest whether to delete on GET request","title":"Services"},{"location":"admin/admin-ui/services-menu/#services","text":"This menu allows user to configure Cache Provider and LDAP schemas which can be used by the auth server.","title":"Services"},{"location":"admin/admin-ui/services-menu/#cache-provider-configuration","text":"The following cache providers are supported in Janssen's auth server: In Memory : recommended for small deployments only Memcached : recommended for single cache server deployment Redis : recommended for cluster deployments Native Persistence : recommended avoiding additional components' installation. All cache entries are saved in persistence layers.","title":"Cache Provider Configuration"},{"location":"admin/admin-ui/services-menu/#cache-provider-properties","text":"The following tables include the name and description of each Cache Provider's properties.","title":"Cache Provider Properties"},{"location":"admin/admin-ui/services-menu/#cache-configuration","text":"Name Description Cache Provider Type The cache provider type","title":"Cache Configuration"},{"location":"admin/admin-ui/services-menu/#memcached-configuration","text":"Name Description Server Details Server details separated by spaces (e.g. `server1:8080 server2:8081) Max Operation Queue Length Maximum number of operations that can be queued Buffer Size Buffer size in bytes Default Put Expiration Expiration timeout value in seconds Connection Factory Type Connection factory type","title":"Memcached Configuration"},{"location":"admin/admin-ui/services-menu/#in-memory-configuration","text":"Name Description Default Put Expiration Default put expiration timeout value in seconds","title":"In-Memory Configuration"},{"location":"admin/admin-ui/services-menu/#redis-configuration","text":"Name Description Redis Provider Type Type of connection: standalone, clustered, sharded, sentinel Server Details Server details separated by commas (e.g. 'server1:8080,server2:8081') Use SSL Enable SSL communication between Gluu Server and Redis cache Password Redis password Sentinel Master Group Name Sentinel Master Group Name (required if SENTINEL type of connection is selected) SSL Trust Store File Path Directory Path to Trust Store Default Put Expiration Default expiration time for the object put into cache in seconds Max Retry Attempts Max retry attepts in case of failure So Timeout With this option set to a non-zero timeout, a read() call on the InputStream associated with this Socket will block for only this amount of time. If the timeout expires, a java.net.SocketTimeoutException is raised, though the Socket is still valid. The option must be enabled prior to entering the blocking operation to have effect. The timeout must be > 0. A timeout of zero is interpreted as an infinite timeout. Max Idle Connections The cap on the number of \\\"idle\\\" instances in the pool. If maxIdle is set too low on heavily loaded systems it is possible you will see objects being destroyed and almost immediately new objects being created. This is a result of the active threads momentarily returning objects faster than they are requesting them, causing the number of idle objects to rise above maxIdle. The best value for maxIdle for heavily loaded system will vary but the default is a good starting point. Max Total Connections The number of maximum connection instances in the pool Connection Timeout Connection time out","title":"Redis Configuration"},{"location":"admin/admin-ui/services-menu/#native-persistence-configuration","text":"Name Description Default Put Expiration Default expiration time for the object put into cache in seconds Default Cleanup Batch Size Default cleanup batch page size Delete Expired OnGetRequest whether to delete on GET request","title":"Native Persistence Configuration"},{"location":"admin/admin-ui/smtp-menu/","tags":["administration","admin-ui","smtp"],"text":"SMTP Configuration # The description of all the fields in SMTP configuration form: Fields Description SMTP Host Hostname of the SMTP server Connect Protection Protocol to protect connection From Name Name of the sender From Email Address Email Address of the Sender Requires Authentication This checkbox enables sender authentication SMTP User Name Username of the SMTP SMTP User Password Password for the SMTP Requires SSL This checkbox enables the SSL SMTP Port Port number of the SMTP server Keystore","title":"SMTP"},{"location":"admin/admin-ui/smtp-menu/#smtp-configuration","text":"The description of all the fields in SMTP configuration form: Fields Description SMTP Host Hostname of the SMTP server Connect Protection Protocol to protect connection From Name Name of the sender From Email Address Email Address of the Sender Requires Authentication This checkbox enables sender authentication SMTP User Name Username of the SMTP SMTP User Password Password for the SMTP Requires SSL This checkbox enables the SSL SMTP Port Port number of the SMTP server Keystore","title":"SMTP Configuration"},{"location":"admin/admin-ui/userMgmt-menu/","tags":["administration","admin-ui","users"],"text":"Users # This interface allows the administrator to create, edit, delete and search user records in Janssen persistence. The user creation/modification form has First Name, Middle Name, Last Name, Username, Display Name, Email, Status and Password fields populated by default on it. The administrator can select and add more user attributes to the form from the right Available Claims panel. To add a new user claim, please follow this document . Different Admin UI Roles can be assigned to the user in the jansAdminUIRole attribute (to be selected from the Available Claims panel).","title":"Users"},{"location":"admin/admin-ui/userMgmt-menu/#users","text":"This interface allows the administrator to create, edit, delete and search user records in Janssen persistence. The user creation/modification form has First Name, Middle Name, Last Name, Username, Display Name, Email, Status and Password fields populated by default on it. The administrator can select and add more user attributes to the form from the right Available Claims panel. To add a new user claim, please follow this document . Different Admin UI Roles can be assigned to the user in the jansAdminUIRole attribute (to be selected from the Available Claims panel).","title":"Users"},{"location":"admin/admin-ui/webhooks/","tags":["administration","admin-ui","webhooks"],"text":"Webhooks # Gluu Flex Admin UI serves as a powerful web interface designed to streamline the management and configuration of the Janssen Authentication Server. To further extend its capabilities, Gluu Flex Admin UI integrates the use of webhooks, enabling the execution of custom business logic during the creation, update, and deletion of information on the Janssen Authentication Server. The seamless integration of webhooks into this interface enhances its functionality, offering a dynamic and extensible solution. Webhooks are a mechanism for automating workflows by allowing external systems to be notified of specific events. In the context of Gluu Flex Admin UI, webhooks can be mapped to various Admin UI features to execute custom business logic when events associated with those features occur. Administrators can map one or more webhooks to specific feature events using the user interface. Webhook management on the UI # The webhook create/update form consists for following fields. Field Description Required Webhook Id The unique identifier of webhook Yes. Generated by Admin UI Webhook Name The name give to webhook Yes URL The webhook url Yes HTTP Method The type HTTP request (e.g. GET, POST, PUT, PATCH, DELETE ) Yes Description Webhook description No Webhook Headers The HTTP request headers No Request Body The HTTP request body Mandatory for POST, PUT, PATCH requests Enabled Toggle switch to enable/disable webhook Yes Admin UI Features The Admin UI features which can be mapped to the webhook No Once a webhook is created it can be searched, edited or deleted. Shortcodes # When working with webhooks, shortcodes play a crucial role in dynamically injecting data into URLs and request bodies. They allow for flexible and customizable communication between different systems. Shortcode is denoted by curly braces ${} . Using shortcodes in webhook url: Shortcodes can be used in path parameters or query parameters of webhook url. https://example.com/webhook/ ${ inum } /update https://example.com/webhook?action = ${ action } & user_id = ${ userId } Using shortcodes in webhook request-body: Webhook request bodies can utilize placeholders to dynamically populate data sent to the recipient system. { \"username\" : \" ${ username } \" , \"email\" : \" ${ email } \" , \"password\" : \" ${ password } \" } Triggering webhooks # The webhooks can be mapped with one or more Admin UI feature(s) using the webhook create/update form . The following Admin UI features can be mapped to the webhooks. Feature Name Action Permission Custom Script Add/Edit https://jans.io/oauth/config/scripts.write Custom Script Delete https://jans.io/oauth/config/scripts.delete FIDO Configuration Edit https://jans.io/oauth/jans-auth-server/config/properties.write Jans Link Edit https://jans.io/oauth/config/jans-link.write OIDC Clients Add/Edit https://jans.io/oauth/config/openid/clients.write OIDC Clients Delete https://jans.io/oauth/config/openid/clients.delete Scopes Add/Edit https://jans.io/oauth/config/scopes.write Scopes Delete https://jans.io/oauth/config/scopes.delete Schema:Person Add/Edit https://jans.io/oauth/config/attributes.write Schema:Person Delete https://jans.io/oauth/config/attributes.delete SCIM Configuration Edit https://jans.io/scim/config.write SMTP Configuration Edit https://jans.io/oauth/config/smtp.write Users Add/Edit https://jans.io/oauth/config/user.write Users Delete https://jans.io/oauth/config/user.delete When the feature action is performed (e.g. submitting the \"create new user\" form), the Admin UI displays the consent dialog with a list of webhooks that will be triggered upon the successful execution of the event. If the user clicks on the Accept button, all the enabled webhooks will be triggered during the event execution. The Admin UI is unable to proceed with event execution if any webhook fails during the process.","title":"Webhooks"},{"location":"admin/admin-ui/webhooks/#webhooks","text":"Gluu Flex Admin UI serves as a powerful web interface designed to streamline the management and configuration of the Janssen Authentication Server. To further extend its capabilities, Gluu Flex Admin UI integrates the use of webhooks, enabling the execution of custom business logic during the creation, update, and deletion of information on the Janssen Authentication Server. The seamless integration of webhooks into this interface enhances its functionality, offering a dynamic and extensible solution. Webhooks are a mechanism for automating workflows by allowing external systems to be notified of specific events. In the context of Gluu Flex Admin UI, webhooks can be mapped to various Admin UI features to execute custom business logic when events associated with those features occur. Administrators can map one or more webhooks to specific feature events using the user interface.","title":"Webhooks"},{"location":"admin/admin-ui/webhooks/#webhook-management-on-the-ui","text":"The webhook create/update form consists for following fields. Field Description Required Webhook Id The unique identifier of webhook Yes. Generated by Admin UI Webhook Name The name give to webhook Yes URL The webhook url Yes HTTP Method The type HTTP request (e.g. GET, POST, PUT, PATCH, DELETE ) Yes Description Webhook description No Webhook Headers The HTTP request headers No Request Body The HTTP request body Mandatory for POST, PUT, PATCH requests Enabled Toggle switch to enable/disable webhook Yes Admin UI Features The Admin UI features which can be mapped to the webhook No Once a webhook is created it can be searched, edited or deleted.","title":"Webhook management on the UI"},{"location":"admin/admin-ui/webhooks/#shortcodes","text":"When working with webhooks, shortcodes play a crucial role in dynamically injecting data into URLs and request bodies. They allow for flexible and customizable communication between different systems. Shortcode is denoted by curly braces ${} . Using shortcodes in webhook url: Shortcodes can be used in path parameters or query parameters of webhook url. https://example.com/webhook/ ${ inum } /update https://example.com/webhook?action = ${ action } & user_id = ${ userId } Using shortcodes in webhook request-body: Webhook request bodies can utilize placeholders to dynamically populate data sent to the recipient system. { \"username\" : \" ${ username } \" , \"email\" : \" ${ email } \" , \"password\" : \" ${ password } \" }","title":"Shortcodes"},{"location":"admin/admin-ui/webhooks/#triggering-webhooks","text":"The webhooks can be mapped with one or more Admin UI feature(s) using the webhook create/update form . The following Admin UI features can be mapped to the webhooks. Feature Name Action Permission Custom Script Add/Edit https://jans.io/oauth/config/scripts.write Custom Script Delete https://jans.io/oauth/config/scripts.delete FIDO Configuration Edit https://jans.io/oauth/jans-auth-server/config/properties.write Jans Link Edit https://jans.io/oauth/config/jans-link.write OIDC Clients Add/Edit https://jans.io/oauth/config/openid/clients.write OIDC Clients Delete https://jans.io/oauth/config/openid/clients.delete Scopes Add/Edit https://jans.io/oauth/config/scopes.write Scopes Delete https://jans.io/oauth/config/scopes.delete Schema:Person Add/Edit https://jans.io/oauth/config/attributes.write Schema:Person Delete https://jans.io/oauth/config/attributes.delete SCIM Configuration Edit https://jans.io/scim/config.write SMTP Configuration Edit https://jans.io/oauth/config/smtp.write Users Add/Edit https://jans.io/oauth/config/user.write Users Delete https://jans.io/oauth/config/user.delete When the feature action is performed (e.g. submitting the \"create new user\" form), the Admin UI displays the consent dialog with a list of webhooks that will be triggered upon the successful execution of the event. If the user clicks on the Accept button, all the enabled webhooks will be triggered during the event execution. The Admin UI is unable to proceed with event execution if any webhook fails during the process.","title":"Triggering webhooks"},{"location":"admin/kubernetes-ops/","tags":["administration","kubernetes","operations"],"text":"Overview # This Operation guide helps you learn about the common operations for Gluu Flex on Kubernetes. Note Since Flex = Janssen + Admin-UI. The Kubernetes Operations in Gluu Flex are identitical to Janssen . You will mostly only need to change the helm chart reference from janssen/janssen to gluu-flex/gluu , along with the helm release name and namespace. Here's an example how would the upgrade of Flex looks like. Common Operations # Upgrade Admin-UI Private Scaling Backup and Restore Certificate Management Customization Start Order Logs External Secrets and Configmaps Health Check TUI K8s Custom Attributes Jans SAML/Keycloak Memory Dump","title":"Overview"},{"location":"admin/kubernetes-ops/#overview","text":"This Operation guide helps you learn about the common operations for Gluu Flex on Kubernetes. Note Since Flex = Janssen + Admin-UI. The Kubernetes Operations in Gluu Flex are identitical to Janssen . You will mostly only need to change the helm chart reference from janssen/janssen to gluu-flex/gluu , along with the helm release name and namespace. Here's an example how would the upgrade of Flex looks like.","title":"Overview"},{"location":"admin/kubernetes-ops/#common-operations","text":"Upgrade Admin-UI Private Scaling Backup and Restore Certificate Management Customization Start Order Logs External Secrets and Configmaps Health Check TUI K8s Custom Attributes Jans SAML/Keycloak Memory Dump","title":"Common Operations"},{"location":"admin/kubernetes-ops/admin-ui-private/","tags":["administration","kubernetes","operations","private","internal","admin-ui"],"text":"Overview # This document demonstrates a method to override the URLs in the admin-ui used to connect to the backend services, such as the config API. This way the calls are made privately without hitting the FQDN through the internet. Configuration # We will install nginx in ingress-nginx namespace using the following command: helm install ingress-nginx ingress-nginx/ingress-nginx -n ingress-nginx and thus, the svc is accessible at ingress-nginx-controller.ingress-nginx.svc.cluster.local Modify values.yaml : admin-ui : usrEnvs : normal : CN_CONFIG_API_BASE_URL : https://ingress.local:8443 CN_AUTH_BASE_URL : https://ingress.local:8443 CN_TOKEN_SERVER_BASE_URL : https://ingress-nginx-controller.ingress-nginx.svc.cluster.local config-api : usrEnvs : normal : CN_TOKEN_SERVER_BASE_URL : https://ingress-nginx-controller.ingress-nginx.svc.cluster.local nginx-ingress : ingress : hosts : - demoexample.gluu.org # adjust Gluu FQDN used as needed - ingress-nginx-controller.ingress-nginx.svc.cluster.local - ingress.local Deploy the flex helm chart using the updated values.yaml To allow the browser to access internal service, add an entry inside /etc/hosts file: 127.0.0.1 ingress.local ingress-nginx-controller.ingress-nginx.svc.cluster.local By default, the ingress-nginx-controller deployment uses fake certificate generated by k8s. Add a new certificate (self-signed certificate and key are sufficient) as the default certificate into the ingress controller. Generate SSL cert and key using your preferred tool. Make sure to add domain ingress-nginx-controller.ingress-nginx.svc.cluster.local and ingress.local in SAN section. Example: openssl req -x509 -newkey rsa:4096 -sha256 -days 365 -nodes -keyout ingress.local.key -out ingress.local.crt -subj \"/CN=ingress.local\" -addext \"subjectAltName=DNS:ingress.local,DNS:ingress-nginx-controller.ingress-nginx.svc.cluster.local\" Create secrets to store the certificate and key, for example: kubectl -n create secret tls internal-tls-certificate --cert /path/to/cert --key /path/to/key Modify the ingress-nginx-controller deployment: apiVersion : apps/v1 kind : Deployment metadata : name : ingress-nginx-controller namespace : ingress-nginx spec : template : spec : containers : - args : # some arguments are omitted # add a new argument to load self-signed cert - --default-ssl-certificate=/internal-tls-certificate Rollout restart the ingress-nginx-controller deployment. Expose the service IP (port 443) to host (port 8443): kubectl -n ingress-nginx port-forward svc/ingress-nginx-controller 8443:443 & OPTIONAL : if the K8s cluster is deployed at a remote VM, make SSH tunneling before accessing the admin-ui web: ssh -N -L 8443:localhost:8443 @ & Hit https://ingress.local:8443 and allow the browser to skip certificate validation. Visit https:///admin","title":"Admin-UI Private"},{"location":"admin/kubernetes-ops/admin-ui-private/#overview","text":"This document demonstrates a method to override the URLs in the admin-ui used to connect to the backend services, such as the config API. This way the calls are made privately without hitting the FQDN through the internet.","title":"Overview"},{"location":"admin/kubernetes-ops/admin-ui-private/#configuration","text":"We will install nginx in ingress-nginx namespace using the following command: helm install ingress-nginx ingress-nginx/ingress-nginx -n ingress-nginx and thus, the svc is accessible at ingress-nginx-controller.ingress-nginx.svc.cluster.local Modify values.yaml : admin-ui : usrEnvs : normal : CN_CONFIG_API_BASE_URL : https://ingress.local:8443 CN_AUTH_BASE_URL : https://ingress.local:8443 CN_TOKEN_SERVER_BASE_URL : https://ingress-nginx-controller.ingress-nginx.svc.cluster.local config-api : usrEnvs : normal : CN_TOKEN_SERVER_BASE_URL : https://ingress-nginx-controller.ingress-nginx.svc.cluster.local nginx-ingress : ingress : hosts : - demoexample.gluu.org # adjust Gluu FQDN used as needed - ingress-nginx-controller.ingress-nginx.svc.cluster.local - ingress.local Deploy the flex helm chart using the updated values.yaml To allow the browser to access internal service, add an entry inside /etc/hosts file: 127.0.0.1 ingress.local ingress-nginx-controller.ingress-nginx.svc.cluster.local By default, the ingress-nginx-controller deployment uses fake certificate generated by k8s. Add a new certificate (self-signed certificate and key are sufficient) as the default certificate into the ingress controller. Generate SSL cert and key using your preferred tool. Make sure to add domain ingress-nginx-controller.ingress-nginx.svc.cluster.local and ingress.local in SAN section. Example: openssl req -x509 -newkey rsa:4096 -sha256 -days 365 -nodes -keyout ingress.local.key -out ingress.local.crt -subj \"/CN=ingress.local\" -addext \"subjectAltName=DNS:ingress.local,DNS:ingress-nginx-controller.ingress-nginx.svc.cluster.local\" Create secrets to store the certificate and key, for example: kubectl -n create secret tls internal-tls-certificate --cert /path/to/cert --key /path/to/key Modify the ingress-nginx-controller deployment: apiVersion : apps/v1 kind : Deployment metadata : name : ingress-nginx-controller namespace : ingress-nginx spec : template : spec : containers : - args : # some arguments are omitted # add a new argument to load self-signed cert - --default-ssl-certificate=/internal-tls-certificate Rollout restart the ingress-nginx-controller deployment. Expose the service IP (port 443) to host (port 8443): kubectl -n ingress-nginx port-forward svc/ingress-nginx-controller 8443:443 & OPTIONAL : if the K8s cluster is deployed at a remote VM, make SSH tunneling before accessing the admin-ui web: ssh -N -L 8443:localhost:8443 @ & Hit https://ingress.local:8443 and allow the browser to skip certificate validation. Visit https:///admin","title":"Configuration"},{"location":"admin/kubernetes-ops/upgrade/","tags":["administration","kubernetes","operations","helm","upgrade"],"text":"This guide shows how to upgrade a Gluu Flex helm deployment. helm ls -n Keep note of the helm release version Add your changes to override.yaml Apply your upgrade: helm upgrade gluu-flex/gluu -n -f override.yaml --version=replace-flex-version","title":"Upgrade"},{"location":"admin/recipes/","tags":["administration","recipes"],"text":"Overview # Please use the left navigation menu to browse the content of this section while we are still working on developing content for Overview page.","title":"Overview"},{"location":"admin/recipes/#overview","text":"Please use the left navigation menu to browse the content of this section while we are still working on developing content for Overview page.","title":"Overview"},{"location":"admin/recipes/getting-started-rancher/","text":"Overview # Gluu Flex (\u201cFlex\u201d) is a cloud-native digital identity platform that enables organizations to authenticate and authorize people and software through the use of open standards like OpenID Connect, OAuth, and FIDO. It is a downstream commercial distribution of the Linux Foundation Janssen Project software, plus a web administration tool(Gluu Admin-UI). SUSE Rancher\u2019s helm-based deployment approach simplifies the deployment and configuration of Flex, enabling organizations to take advantage of Flex\u2019s modular design to improve their security posture while simultaneously enabling just-in-time auto-scaling. The key services of Flex include: (REQUIRED) Jans Auth Server : This component is the OAuth Authorization Server, the OpenID Connect Provider, and the UMA Authorization Server for person and software authentication. This service must be Internet-facing. (REQUIRED) Jans Config API : The API to configure the auth-server and other components is consolidated in this component. This service should not be Internet-facing. Gluu Admin UI : Web admin tool for ad-hoc configuration. Jans Fido : This component provides the server-side endpoints to enroll and validate devices that use FIDO. It provides both FIDO U2F (register, authenticate) and FIDO 2 (attestation, assertion) endpoints. This service must be Internet-facing. Jans SCIM : System for Cross-domain Identity Management ( SCIM ) is JSON/REST API to manage user data. Use it to add, edit and update user information. This service should not be Internet-facing. Jans Casa : A self-service web portal for end-users to manage authentication and authorization preferences for their account in the Gluu Flex server. Typically, it enables people to manage their MFA credentials, like FIDO tokens and OTP authenticators. It's also extensible if your organization has any other self-service requirements. Building Blocks # Scope # In this Quickstart Guide, we will: Deploy Flex and add some users. Enable two-factor authentication. Protect content on an Apache web server with OpenID Connect. Audience # This document is intended for DevOps engineers, site reliability engineers (SREs), platform engineers, software engineers, and developers who are responsible for managing and running stateful workloads in Kubernetes clusters. Technical overview # In addition to the core services listed in the Introduction above, the SUSE Rancher deployment includes the following components: PostgreSQL/MySQL : SQL database dialect used to store configuration, people clients, sessions and other data needed for Gluu Flex operation. Cert Manager : Used for managing X.509 certificates and crypto keys lifecycle in Janssen Server. Key Rotation : A cronjob that implements Cert Manager to rotate the auth keys Configuration job : loads (generate/restore) and dumps (backup) the configuration and secrets. Persistence job : This job loads initial data for the backend used (SQL or Couchbase). ConfigMaps : Stores configuration needed for Flex environment setup. Secrets : Contains sensitive or confidential data such as a password, a token, or a key. Config and Secret keys # The Configuration job creates a set of configurations and secrets used by all services in the Flex setup. To check the values of the configuration keys(configmaps) in the installation: kubectl get cm cn -o json -n To check the values of the secret keys in installation: kubectl get secret cn -o json -n Gluu Config Keys # Key Example Values admin_email team@gluu.org admin_inum d3afef58-c026-4514-9d4c-e0a3efb4c29d admin_ui_client_id 1901.a6575c1e-4688-4c11-8c95-d9e570b13ee8 auth_enc_keys RSA1_5 RSA-OAEP auth_key_rotated_at 1653517558 auth_legacyIdTokenClaims false auth_openidScopeBackwardCompatibility false auth_openid_jks_fn /etc/certs/auth-keys.jks auth_openid_jwks_fn /etc/certs/auth-keys.json casa_client_id 0008-db36db1f-025e-4164-aeed-f82df064eee8 auth_sig_keys RS256 RS384 RS512 ES256 ES384 ES512 PS384 PS512 city Austin country_code US default_openid_jks_dn_name CN=Janssen Auth CA Certificate fido2ConfigFolder /etc/jans/conf/fido2 hostname demoexample.gluu.org jca_client_id 1801.4df6c3ba-ebf6-4836-8fb5-6da927586f61 optional_scopes [\\\"casa\\\", \\\"sql\\\", \\\"fido2\\\", \\\"scim\\\"] orgName Gluu tui_client_id 2000.9313cd4b-147c-4a67-96be-8a69ddbaf7e9 scim_client_id 1201.1cbcc731-3fca-4668-a480-1b5f5a7d6a53 state TX token_server_admin_ui_client_id 1901.57a858dc-69f3-4967-befe-e089fe376638 Gluu Secret Keys # Key Example Values admin_ui_client_encoded_pw QlBMMTZUZWVYeWczVlpNUk1XN0pzdzrg admin_ui_client_pw WnJYZEcyVlNBWG9d auth_jks_base64 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx auth_openid_jks_pass TWZoR3Rlb0NnUHEP auth_openid_key_base64 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx casa_client_encoded_pw b3NabG9oVGNncFVVWFpxNEJMU3V0dzrg casa_client_pw M1g0Z1dEbGNPQ19d encoded_admin_password e3NzaGF9eGpOaDRyblU3dzJZbmpPclovMUlheTdkR0RrOTdLe encoded_salt Um9NSEJnOU9IbTRvRkJHVVZETVZIeXEP jca_client_encoded_pw Um9NSEJnOU9IbTRvRkJHVVZETVZIeX58 jca_client_pw Um9NSEJnOU9IbTRvR otp_configuration xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx pairwiseCalculationKey ZHd2VW01Y3VOUW6638ZHd2VW pairwiseCalculationSalt ZHd2VW01Y3VOUW6638ZHd2VW0 plugins_admin_ui_properties xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx tui_client_encoded_pw ZHd2VW01Y3VOUW66388PS512 tui_client_pw AusZHd2VW01Y3VOUW6638 scim_client_encoded_pw UZHd2VW01Y3VOUW6638ZHd2VW01Y3VOUW6638 scim_client_pw ZHd2VW01Y3VOUW6638 sql_password ZHd2VW01Y3V638 ssl_ca_cert xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ssl_ca_key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ssl_cert xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ssl_csr xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ssl_key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx super_gluu_creds xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx3 token_server_admin_ui_client_encoded_pw Q1Z1cmtYWUlYSVg4U2tLTldVcnZVTUF token_server_admin_ui_client_pw ZHd2VW01Y3VOUW6638 Prerequisites # SUSE Rancher installed with an accessible UI Kubernetes cluster running on SUSE Rancher with at least 1 worker node Sufficient RBAC permissions to deploy and manage applications in the cluster. LinuxIO kernel modules on the worker nodes Docker running locally (Linux preferred) Essential tools and CLI utilities are installed on your local workstation and are available in your $PATH : curl , kubectl An entry in the /etc/hosts file of your local workstation to resolve the hostname of the Gluu Flex installation. This step is for testing purposes. Installation # Summary of steps : Install Database: Note For the Database test setup to work, a PV provisioner support must be present in the underlying infrastructure. Install PostgreSQL database # Note If you are willing to use MySQL installation, skip this section and head to the Install MySQL section. To install a quick setup with PostgreSQL as the backend, you need to provide the connection parameters of a fresh setup. For a test setup, you can follow the below instructions: Apps --> Charts and search for Postgres . Click on Install on the right side of the window. Create a new namespace called postgres and hit Next . You should be on the Edit YAML page. Modify the below keys as desired. These values will be inputted in the installation of Gluu Flex Key auth.database auth.username auth.password Click Install at the bottom right of the page. Install MySQL database # Note Skip this section if you installed PostgreSQL . This section is only needed if you are willing to use MySQL. To install a quick setup with MySQL as the backend, you need to provide the connection parameters of a fresh setup. For a test setup, you can follow the below instructions: Open a kubectl shell from the top right navigation menu >_ . Run: helm repo add bitnami https://charts.bitnami.com/bitnami helm repo update kubectl create ns gluu #Create gluu namespace Pass in a custom password for the database. Here we used Test1234# . The admin user will be left as root . Notice we are installing in the gluu namespace. Run helm install my-release --set auth.rootPassword=Test1234#,auth.database=jans bitnami/mysql -n gluu Successful Installation # After the installation is successful, you should have a Statefulset active in the rancher UI as shown in the screenshot below. Install Nginx-Ingress , if you are not using Istio ingress helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx helm repo add stable https://charts.helm.sh/stable helm repo update helm install nginx ingress-nginx/ingress-nginx To get the Loadbalancer IP: kubectl get svc nginx-ingress-nginx-controller --output jsonpath='{.status.loadBalancer.ingress[0].ip}' Install Gluu Flex: Head to Apps --> Charts and search for Gluu Click on Install on the right side of the window. Change the namespace from default to gluu , then click on Next . Scroll through the sections to get familiar with the options. For minimal setup follow with the next instructions. Add License SSA . Before initiating the setup, please obtain an SSA for Flex trial, after which you will issued a JWT. Click on the Persistence section. Change SQL database host uri to postgresql.postgres.svc.cluster.local in the case of PostgreSQL or my-release-mysql.gluu.svc.cluster.local in the case of MySQL . Also set SQL database username , SQL password , and SQL database name to the values you used during the database installation. To enable Casa and the Admin UI, navigate to the Optional Services section and check the Enable casa and boolean flag to enable admin UI boxes. You can also enable different services like Client API and Jackrabbit . Click on the section named Ingress and enable all the endpoints. You might add LB IP or address if you don't have FQDN for Gluu . To pass your FQDN or Domain that is intended to serve the Gluu Flex IDP, head to the Configuration section: Add your FQDN and check the box Is the FQDN globally resolvable . Click on the Edit YAML tab and add your FQDN to nginx-ingress.ingress.hosts and nginx-ingress.ingress.tls.hosts . Click on Install on the bottom right of the window. Note You can upgrade your installation after the deployment. To do that, go to the SUSE Rancher Dashboard -> Apps -> Installed Apps -> gluu -> Click on the 3 dots on the right -> Upgrade -> Make your changes -> Click Update. The running deployment and services of different Gluu Flex components like casa , admin-ui , scim , auth-server , etc can be viewed by navigating through the SUSE Rancher. Go to Workloads and see the running pods. Go under Service Discovery and checkout the Ingresses and Services . All deployed components should be in a healthy and running state like in the screenshot shown below. Connecting to the Setup # Note You can skip this section if you have a globally resolvable FQDN . In the event you used microk8s or your fqdn is not registered, the below steps will help with connecting to your setup. To access the setup from a browser or another VM, we need to change the ingress class annotation from kubernetes.io/ingress.class: nginx to kubernetes.io/ingress.class: public e.g., for the specific component you want to access publicly in the browser; Navigate through the SUSE Rancher UI to Service Discovery -> Ingresses Choose the ingress for the targeted component. For example gluu-nginx-ingress-auth-server for auth-server Click on the three dots in the top right corner Click on Edit Yaml On line 8, change the kubernetes.io/ingress.class annotation value from nginx to public Click Save The LoadBalancer IP needs to get mapped inside /etc/hosts with the domain chosen for gluu flex . If the domain you used in the setup is demoexample.gluu.org: 3.65.27.95 demoexample.gluu.org You can do the same edit for every component you want to access publicly from the browser. Testing Configuration endpoints # Try accessing some Gluu Flex endpoints like https://demoexample.gluu.org/.well-known/openid-configuration in the browser and you'll get back a JSON response; Note that you can also access those endpoints via curl command, E.g. curl -k https://demoexample.gluu.org/.well-known/openid-configuration You should get a similar response like the one below; {\"version\":\"1.1\",\"issuer\":\"https://demoexample.gluu.org\",\"attestation\":{\"base_path\":\"https://demoexample.gluu.org/jans-fido2/restv1/attestation\",\"options_enpoint\":\"https://demoexample.gluu.org/jans-fido2/restv1/attestation/options\",\"result_enpoint\":\"https://demoexample.gluu.org/jans-fido2/restv1/attestation/result\"},\"assertion\":{\"base_path\":\"https://demoexample.gluu.org/jans-fido2/restv1/assertion\",\"options_enpoint\":\"https://demoexample.gluu.org/jans-fido2/restv1/assertion/options\",\"result_enpoint\":\"https://demoexample.gluu.org/jans-fido2/restv1/assertion/result\"}} Login and Add a New User # After inputting the license keys, you can then use admin and the password you set to login to the Admin UI and you should see the Admin UI dashboard. You could also add another test user via the admin UI that will be used for testing Casa and 2FA as shown in the screenshot below. Navigate to Users and click on + in the top right corner to add a user. Testing Casa # Jans Casa (\"Casa\") is a self-service web portal for managing account security preferences. The primary use case for Casa is self-service 2FA, but other use cases and functionalities can be supported via Casa plugins. Although you have not enabled two-factor authentication yet, you should still be able to login to Casa as the admin user and the password is the one you set during installation. Point your browser to https://demoexample.gluu.org/jans-casa and you should be welcomed by the Casa login page as shown below. After logging in, you'll be welcomed by the home page as shown below. Enabling Two-Factor Authentication # In this part, we are going to enable two standard authentication mechanisms: OTP and FIDO. This can be done through the admin UI. 2FA can be turned on by clicking the switch in the Second Factor Authentication widget. By default, you will be able to choose from a few 2FA policies: Always (upon every login attempt) If the location (e.g. city) detected in the login attempt is unrecognized If the device used to login is unrecognized To reduce the chance of account lockout, enroll at least two different types of 2FA credentials -- e.g. one security key and one OTP app; or one OTP app and one SMS phone number, etc. This way, regardless of which device you're using to access a protected resource, you will have a usable option for passing strong authentication. To enable 2FA, firstly the OTP and FIDO components have to be enabled in the Casa admin UI then login to Casa as an end user, and register an OTP device (i.e. Google Authenticator) and a FIDO device. Register OTP device To add a new OTP token, navigate to 2FA credentials > OTP Tokens. You can either add a soft OTP token by choosing the Soft token option or a hard token by choosing the Hard Token Option Check the soft OTP token and click ready Before proceeding to the next step, Download Google Authenticator from Google Play or Appstore Then proceed and scan the QR code with your app Enter the 6-digit code that appears in your authenticator app and validate the enrollment. Register Fido device To add a new FIDO 2 credential, navigate to 2FA credentials > Security Keys and built-in Platform Authenticators Insert the fido key and click Ready. Casa will prompt you to press the button on the key. Add a nickname and click Add. Once added, the new device will appear in a list on the same page. Click the pencil to edit the device's nickname Testing Apache OIDC Locally # In this part, we are going to use docker to locally configure an apache web server, and then install the mod_auth_openidc module and configure it accordingly. Using local docker containers, our approach is to first register a client, then spin up two Apache containers, one serving static content (with server-side includes configured so we can display headers and environment information), and one acting as the OpenID Connect authenticating reverse proxy. Register an OpenID Connect client # On the Janssen server, you can register a new client in the Flex Admin UI or the jans-cli. In this section, we are going to show both ways of doing it from the Admin UI and using jans-cli Admin UI # Navigate to Auth server -> Clients and click on + in the top right corner to create a client. Take note of the following keys:values because they configure the right client that we need scopes: email_,openid_,profile responseTypes: code The screenshot below shows an example of the Admin UI section from where a client is created Jans TUI # On the Janssen server, we are going to register a new client using the jans-cli. There are two ways you can register an OIDC client with the Janssen server, Manual Client Registration and Dynamic Client Registration (DCR). Here we will use manual client registration. We will use jans-tui tool provided by the Janssen server. jans-tui has a menu-driven interface that makes it easy to configure the Janssen server. Here we will use the menu-driven approach to register a new client. Download jans-cli-tui from the release assets depending on your OS. For example: wget https://github.com/JanssenProject/jans/releases/download/vreplace-janssen-version/jans-cli-tui-linux-ubuntu-X86-64.pyz Now we have jans-cli-tui-linux-ubuntu-X86-64.pyz downloaded. Now we can grab the FQDN, client-id, client-secret, and connect using the following commands: FQDN= #Add your FQDN here TUI_CLIENT_ID=$(kubectl get cm cn -n --template={{.data.tui_client_id}}) TUI_CLIENT_SECRET=$(kubectl get secret cn -n --template={{.data.tui_client_pw}} | base64 -d) #add -noverify if your FQDN is not registered Get schema file using this command python3 jans-cli-tui-linux-ubuntu-X86-64.pyz --host --client-id --client-secret --no-tui --schema /components/schemas/Client Add values for required params and store this JSON in a text file. Take keynote of the following properties. schema-json-file.json { \"dn\": null, \"inum\": null, \"displayName\": \"\", \"clientSecret\": \"\", \"frontChannelLogoutUri\": null, \"frontChannelLogoutSessionRequired\": null, \"registrationAccessToken\": null, \"clientIdIssuedAt\": null, \"clientSecretExpiresAt\": null, \"redirectUris\": [ \"\" ], \"claimRedirectUris\": null, \"responseTypes\": [ \"code\" ], \"grantTypes\": [ \"authorization_code\" ], \"applicationType\": \"web\", \"contacts\": null, \"idTokenTokenBindingCnf\": null, \"logoUri\": null, \"clientUri\": null, \"policyUri\": null, \"tosUri\": null, \"jwksUri\": null, \"jwks\": null, \"sectorIdentifierUri\": null, \"subjectType\": \"public\", \"idTokenSignedResponseAlg\": null, \"idTokenEncryptedResponseAlg\": null, \"idTokenEncryptedResponseEnc\": null, \"userInfoSignedResponseAlg\": null, \"userInfoEncryptedResponseAlg\": null, \"userInfoEncryptedResponseEnc\": null, \"requestObjectSigningAlg\": null, \"requestObjectEncryptionAlg\": null, \"requestObjectEncryptionEnc\": null, \"tokenEndpointAuthMethod\": \"client_secret_basic\", \"tokenEndpointAuthSigningAlg\": null, \"defaultMaxAge\": null, \"requireAuthTime\": null, \"defaultAcrValues\": null, \"initiateLoginUri\": null, \"postLogoutRedirectUris\": null, \"requestUris\": null, \"scopes\": [ \"email\", \"openid\", \"profile\" ], \"claims\": null, \"trustedClient\": false, \"lastAccessTime\": null, \"lastLogonTime\": null, \"persistClientAuthorizations\": null, \"includeClaimsInIdToken\": false, \"refreshTokenLifetime\": null, \"accessTokenLifetime\": null, \"customAttributes\": null, \"customObjectClasses\": null, \"rptAsJwt\": null, \"accessTokenAsJwt\": null, \"accessTokenSigningAlg\": null, \"disabled\": false, \"authorizedOrigins\": null, \"softwareId\": null, \"softwareVersion\": null, \"softwareStatement\": null, \"attributes\": null, \"backchannelTokenDeliveryMode\": null, \"backchannelClientNotificationEndpoint\": null, \"backchannelAuthenticationRequestSigningAlg\": null, \"backchannelUserCodeParameter\": null, \"expirationDate\": null, \"deletable\": false, \"jansId\": null, \"description\": null } Now you can use that JSON file as input to the command below and register your client python3 jans-cli-tui-linux-ubuntu-X86-64.pyz --host --client-id --client-secret --no-tui --operation-id=post-oauth-openid-client --data /schema-json-file.json After the client is successfully registered, there will be data that describes the newly registered client. Some of these values, like inum and clientSecret , will be required before we configure mod_auth_openidc So keep in mind that we shall get back to this. Create an Application Container # An application docker container will be run locally which will act as the protected resource (PR) / external application. The following files have code for the small application. We shall create a directory locally / on your machine called test and add the required files. Firstly create a project folder named test by running mkdir test && cd test and add the following files with their content; app.conf ServerRoot \"/usr/local/apache2\" Listen 80 LoadModule mpm_event_module modules/mod_mpm_event.so LoadModule authz_core_module modules/mod_authz_core.so LoadModule include_module modules/mod_include.so LoadModule filter_module modules/mod_filter.so LoadModule mime_module modules/mod_mime.so LoadModule log_config_module modules/mod_log_config.so LoadModule setenvif_module modules/mod_setenvif.so LoadModule unixd_module modules/mod_unixd.so LoadModule dir_module modules/mod_dir.so User daemon Group daemon AllowOverride none Require all denied DocumentRoot \"/usr/local/apache2/htdocs\" Options Indexes FollowSymLinks Includes AllowOverride None Require all granted SetEnvIf X-Remote-User \"(.*)\" REMOTE_USER=$0 SetEnvIf X-Remote-User-Name \"(.*)\" REMOTE_USER_NAME=$0 SetEnvIf X-Remote-User-Email \"(.*)\" REMOTE_USER_EMAIL=$0 DirectoryIndex index.html Require all denied ErrorLog /proc/self/fd/2 LogLevel warn LogFormat \"%h %l %u %t \\\"%r\\\" %>s %b \\\"%{Referer}i\\\" \\\"%{User-Agent}i\\\"\" combined LogFormat \"%h %l %u %t \\\"%r\\\" %>s %b\" common CustomLog /proc/self/fd/1 common TypesConfig conf/mime.types AddType application/x-compress .Z AddType application/x-gzip .gz .tgz AddType text/html .shtml AddOutputFilter INCLUDES .shtml user.shtml Hello User

              Hello !

              You authenticated as:

              Your email address is:

              Environment:

              !

              index.html Hello World

              Hello world!

              Dockerfile FROM httpd:2.4.54@sha256:c9eba4494b9d856843b49eb897f9a583a0873b1c14c86d5ab77e5bdedd6ad05d # \"Created\": \"2022-06-08T18:45:46.260791323Z\" , \"Version\":\"2.4.54\" RUN apt-get update \\ && apt-get install -y --no-install-recommends wget ca-certificates libcjose0 libhiredis0.14 apache2-api-20120211 apache2-bin\\ && wget https://github.com/zmartzone/mod_auth_openidc/releases/download/v2.4.11.2/libapache2-mod-auth-openidc_2.4.11.2-1.buster+1_amd64.deb \\ && dpkg -i libapache2-mod-auth-openidc_2.4.11.2-1.buster+1_amd64.deb \\ && ln -s /usr/lib/apache2/modules/mod_auth_openidc.so /usr/local/apache2/modules/mod_auth_openidc.so \\ && rm -rf /var/log/dpkg.log /var/log/alternatives.log /var/log/apt \\ && touch /usr/local/apache2/conf/extra/secret.conf \\ && touch /usr/local/apache2/conf/extra/oidc.conf RUN echo \"\\n\\nLoadModule auth_openidc_module modules/mod_auth_openidc.so\\n\\nInclude conf/extra/secret.conf\\nInclude conf/extra/oidc.conf\\n\" >> /usr/local/apache2/conf/httpd.conf gluu.secret.conf OIDCClientID OIDCCryptoPassphrase OIDCClientSecret OIDCResponseType code OIDCScope \"openid email profile\" OIDCProviderTokenEndpointAuth client_secret_basic OIDCSSLValidateServer Off OIDCRedirectURI http://localhost:8111/oauth2callback OIDCCryptoPassphrase Require valid-user AuthType openid-connect After, run an Apache container which will play the role of an application being protected by the authenticating reverse proxy. docker run -dit -p 8110:80 \\ -v \"$PWD/app.conf\":/usr/local/apache2/conf/httpd.conf \\ -v \"$PWD/index.html\":/usr/local/apache2/htdocs/index.html \\ -v \"$PWD/user.shtml\":/usr/local/apache2/htdocs/user.shtml \\ --name apache-app httpd:2.4 Note that we are using a popular pre-built image useful for acting as a reverse proxy for authentication in front of an application. It contains a stripped-down Apache with minimal modules, and adds the mod_auth_openidc module for performing OpenID Connect authentication. Make a test curl command call to ensure you get back some content as shown in the screenshot below curl http://localhost:8110/user.shtml Create an Authenticating Reverse Proxy Container # We shall use Apache, but this time we use a Docker image that has mod_auth_oidc installed and configured. This proxy will require authentication, handle the authentication flow with redirects, and then forward requests to the application. In order to use this, you will need to have registered a new OpenID Connect client on the Janssen server. We did that in the step 1 above Add the following files to the test folder. oidc.conf # Unset to make sure clients can't control these RequestHeader unset X-Remote-User RequestHeader unset X-Remote-User-Name RequestHeader unset X-Remote-User-Email # If you want to see tons of logs for your experimentation #LogLevel trace8 OIDCClientID OIDCProviderMetadataURL https://idp-proxy.med.stanford.edu/auth/realms/med-all/.well-known/openid-configuration #OIDCProviderMetadataURL https://idp-proxy-stage.med.stanford.edu/auth/realms/choir/.well-known/openid-configuration OIDCRedirectURI http://localhost:8111/oauth2callback OIDCScope \"openid email profile\" OIDCRemoteUserClaim principal OIDCPassClaimsAs environment AuthType openid-connect Require valid-user ProxyPass http://app:80/ ProxyPassReverse http://app:80/ RequestHeader set X-Remote-User %{OIDC_CLAIM_principal}e RequestHeader set X-Remote-User-Name %{OIDC_CLAIM_name}e RequestHeader set X-Remote-User-Email %{OIDC_CLAIM_email}e proxy.conf # This is the main Apache HTTP server configuration file. For documentation, see: # http://httpd.apache.org/docs/2.4/ # http://httpd.apache.org/docs/2.4/mod/directives.html # # This is intended to be a hardened configuration, with minimal security surface area necessary # to run mod_auth_openidc. ServerRoot \"/usr/local/apache2\" Listen 80 LoadModule mpm_event_module modules/mod_mpm_event.so LoadModule authn_file_module modules/mod_authn_file.so LoadModule authn_core_module modules/mod_authn_core.so LoadModule authz_host_module modules/mod_authz_host.so LoadModule authz_groupfile_module modules/mod_authz_groupfile.so LoadModule authz_user_module modules/mod_authz_user.so LoadModule authz_core_module modules/mod_authz_core.so LoadModule access_compat_module modules/mod_access_compat.so LoadModule auth_basic_module modules/mod_auth_basic.so LoadModule reqtimeout_module modules/mod_reqtimeout.so LoadModule filter_module modules/mod_filter.so LoadModule mime_module modules/mod_mime.so LoadModule log_config_module modules/mod_log_config.so LoadModule env_module modules/mod_env.so LoadModule headers_module modules/mod_headers.so LoadModule setenvif_module modules/mod_setenvif.so #LoadModule version_module modules/mod_version.so LoadModule proxy_module modules/mod_proxy.so LoadModule proxy_http_module modules/mod_proxy_http.so LoadModule unixd_module modules/mod_unixd.so #LoadModule status_module modules/mod_status.so #LoadModule autoindex_module modules/mod_autoindex.so LoadModule dir_module modules/mod_dir.so LoadModule alias_module modules/mod_alias.so User daemon Group daemon ServerAdmin you@example.com AllowOverride none Require all denied DocumentRoot \"/usr/local/apache2/htdocs\" Options Indexes FollowSymLinks AllowOverride None Require all granted DirectoryIndex index.html Options None Require all denied Require all denied ErrorLog /proc/self/fd/2 LogLevel warn LogFormat \"%h %l %u %t \\\"%r\\\" %>s %b \\\"%{Referer}i\\\" \\\"%{User-Agent}i\\\"\" combined LogFormat \"%h %l %u %t \\\"%r\\\" %>s %b\" common LogFormat \"%h %l %u %t \\\"%r\\\" %>s %b \\\"%{Referer}i\\\" \\\"%{User-Agent}i\\\" %I %O\" combinedio CustomLog /proc/self/fd/1 common ScriptAlias /cgi-bin/ \"/usr/local/apache2/cgi-bin/\" AllowOverride None Options None Require all granted RequestHeader unset Proxy early TypesConfig conf/mime.types AddType application/x-compress .Z AddType application/x-gzip .gz .tgz Include conf/extra/proxy-html.conf SSLRandomSeed startup builtin SSLRandomSeed connect builtin TraceEnable off ServerTokens Prod ServerSignature Off LoadModule auth_openidc_module modules/mod_auth_openidc.so Include conf/extra/secret.conf Include conf/extra/oidc.conf Edit the file to include the client secret for the client you created during DCR, and add a securely generated pass phrase for the session keys docker build --pull -t apache-oidc -f Dockerfile . docker run -dit -p 8111:80 \\ -v \"$PWD/proxy.conf\":/usr/local/apache2/conf/httpd.conf \\ -v \"$PWD/gluu.secret.conf\":/usr/local/apache2/conf/extra/secret.conf \\ -v \"$PWD/oidc.conf\":/usr/local/apache2/conf/extra/oidc.conf \\ --link apache-app:app \\ --name apache-proxy apache-oidc Now open a fresh web browser with private (incognito) mode, and go to this url http://localhost:8111/user.shtml To check the proxy logs docker logs -f apache-proxy To see the app logs docker logs -f apache-app If you modified the configuration files, just restart the proxy. docker restart apache-proxy","title":"Getting Started with Rancher"},{"location":"admin/recipes/getting-started-rancher/#overview","text":"Gluu Flex (\u201cFlex\u201d) is a cloud-native digital identity platform that enables organizations to authenticate and authorize people and software through the use of open standards like OpenID Connect, OAuth, and FIDO. It is a downstream commercial distribution of the Linux Foundation Janssen Project software, plus a web administration tool(Gluu Admin-UI). SUSE Rancher\u2019s helm-based deployment approach simplifies the deployment and configuration of Flex, enabling organizations to take advantage of Flex\u2019s modular design to improve their security posture while simultaneously enabling just-in-time auto-scaling. The key services of Flex include: (REQUIRED) Jans Auth Server : This component is the OAuth Authorization Server, the OpenID Connect Provider, and the UMA Authorization Server for person and software authentication. This service must be Internet-facing. (REQUIRED) Jans Config API : The API to configure the auth-server and other components is consolidated in this component. This service should not be Internet-facing. Gluu Admin UI : Web admin tool for ad-hoc configuration. Jans Fido : This component provides the server-side endpoints to enroll and validate devices that use FIDO. It provides both FIDO U2F (register, authenticate) and FIDO 2 (attestation, assertion) endpoints. This service must be Internet-facing. Jans SCIM : System for Cross-domain Identity Management ( SCIM ) is JSON/REST API to manage user data. Use it to add, edit and update user information. This service should not be Internet-facing. Jans Casa : A self-service web portal for end-users to manage authentication and authorization preferences for their account in the Gluu Flex server. Typically, it enables people to manage their MFA credentials, like FIDO tokens and OTP authenticators. It's also extensible if your organization has any other self-service requirements.","title":"Overview"},{"location":"admin/recipes/getting-started-rancher/#building-blocks","text":"","title":"Building Blocks"},{"location":"admin/recipes/getting-started-rancher/#scope","text":"In this Quickstart Guide, we will: Deploy Flex and add some users. Enable two-factor authentication. Protect content on an Apache web server with OpenID Connect.","title":"Scope"},{"location":"admin/recipes/getting-started-rancher/#audience","text":"This document is intended for DevOps engineers, site reliability engineers (SREs), platform engineers, software engineers, and developers who are responsible for managing and running stateful workloads in Kubernetes clusters.","title":"Audience"},{"location":"admin/recipes/getting-started-rancher/#technical-overview","text":"In addition to the core services listed in the Introduction above, the SUSE Rancher deployment includes the following components: PostgreSQL/MySQL : SQL database dialect used to store configuration, people clients, sessions and other data needed for Gluu Flex operation. Cert Manager : Used for managing X.509 certificates and crypto keys lifecycle in Janssen Server. Key Rotation : A cronjob that implements Cert Manager to rotate the auth keys Configuration job : loads (generate/restore) and dumps (backup) the configuration and secrets. Persistence job : This job loads initial data for the backend used (SQL or Couchbase). ConfigMaps : Stores configuration needed for Flex environment setup. Secrets : Contains sensitive or confidential data such as a password, a token, or a key.","title":"Technical overview"},{"location":"admin/recipes/getting-started-rancher/#config-and-secret-keys","text":"The Configuration job creates a set of configurations and secrets used by all services in the Flex setup. To check the values of the configuration keys(configmaps) in the installation: kubectl get cm cn -o json -n To check the values of the secret keys in installation: kubectl get secret cn -o json -n ","title":"Config and Secret keys"},{"location":"admin/recipes/getting-started-rancher/#gluu-config-keys","text":"Key Example Values admin_email team@gluu.org admin_inum d3afef58-c026-4514-9d4c-e0a3efb4c29d admin_ui_client_id 1901.a6575c1e-4688-4c11-8c95-d9e570b13ee8 auth_enc_keys RSA1_5 RSA-OAEP auth_key_rotated_at 1653517558 auth_legacyIdTokenClaims false auth_openidScopeBackwardCompatibility false auth_openid_jks_fn /etc/certs/auth-keys.jks auth_openid_jwks_fn /etc/certs/auth-keys.json casa_client_id 0008-db36db1f-025e-4164-aeed-f82df064eee8 auth_sig_keys RS256 RS384 RS512 ES256 ES384 ES512 PS384 PS512 city Austin country_code US default_openid_jks_dn_name CN=Janssen Auth CA Certificate fido2ConfigFolder /etc/jans/conf/fido2 hostname demoexample.gluu.org jca_client_id 1801.4df6c3ba-ebf6-4836-8fb5-6da927586f61 optional_scopes [\\\"casa\\\", \\\"sql\\\", \\\"fido2\\\", \\\"scim\\\"] orgName Gluu tui_client_id 2000.9313cd4b-147c-4a67-96be-8a69ddbaf7e9 scim_client_id 1201.1cbcc731-3fca-4668-a480-1b5f5a7d6a53 state TX token_server_admin_ui_client_id 1901.57a858dc-69f3-4967-befe-e089fe376638","title":"Gluu Config Keys"},{"location":"admin/recipes/getting-started-rancher/#gluu-secret-keys","text":"Key Example Values admin_ui_client_encoded_pw QlBMMTZUZWVYeWczVlpNUk1XN0pzdzrg admin_ui_client_pw WnJYZEcyVlNBWG9d auth_jks_base64 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx auth_openid_jks_pass TWZoR3Rlb0NnUHEP auth_openid_key_base64 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx casa_client_encoded_pw b3NabG9oVGNncFVVWFpxNEJMU3V0dzrg casa_client_pw M1g0Z1dEbGNPQ19d encoded_admin_password e3NzaGF9eGpOaDRyblU3dzJZbmpPclovMUlheTdkR0RrOTdLe encoded_salt Um9NSEJnOU9IbTRvRkJHVVZETVZIeXEP jca_client_encoded_pw Um9NSEJnOU9IbTRvRkJHVVZETVZIeX58 jca_client_pw Um9NSEJnOU9IbTRvR otp_configuration xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx pairwiseCalculationKey ZHd2VW01Y3VOUW6638ZHd2VW pairwiseCalculationSalt ZHd2VW01Y3VOUW6638ZHd2VW0 plugins_admin_ui_properties xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx tui_client_encoded_pw ZHd2VW01Y3VOUW66388PS512 tui_client_pw AusZHd2VW01Y3VOUW6638 scim_client_encoded_pw UZHd2VW01Y3VOUW6638ZHd2VW01Y3VOUW6638 scim_client_pw ZHd2VW01Y3VOUW6638 sql_password ZHd2VW01Y3V638 ssl_ca_cert xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ssl_ca_key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ssl_cert xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ssl_csr xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ssl_key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx super_gluu_creds xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx3 token_server_admin_ui_client_encoded_pw Q1Z1cmtYWUlYSVg4U2tLTldVcnZVTUF token_server_admin_ui_client_pw ZHd2VW01Y3VOUW6638","title":"Gluu Secret Keys"},{"location":"admin/recipes/getting-started-rancher/#prerequisites","text":"SUSE Rancher installed with an accessible UI Kubernetes cluster running on SUSE Rancher with at least 1 worker node Sufficient RBAC permissions to deploy and manage applications in the cluster. LinuxIO kernel modules on the worker nodes Docker running locally (Linux preferred) Essential tools and CLI utilities are installed on your local workstation and are available in your $PATH : curl , kubectl An entry in the /etc/hosts file of your local workstation to resolve the hostname of the Gluu Flex installation. This step is for testing purposes.","title":"Prerequisites"},{"location":"admin/recipes/getting-started-rancher/#installation","text":"Summary of steps : Install Database: Note For the Database test setup to work, a PV provisioner support must be present in the underlying infrastructure.","title":"Installation"},{"location":"admin/recipes/getting-started-rancher/#install-postgresql-database","text":"Note If you are willing to use MySQL installation, skip this section and head to the Install MySQL section. To install a quick setup with PostgreSQL as the backend, you need to provide the connection parameters of a fresh setup. For a test setup, you can follow the below instructions: Apps --> Charts and search for Postgres . Click on Install on the right side of the window. Create a new namespace called postgres and hit Next . You should be on the Edit YAML page. Modify the below keys as desired. These values will be inputted in the installation of Gluu Flex Key auth.database auth.username auth.password Click Install at the bottom right of the page.","title":"Install PostgreSQL database"},{"location":"admin/recipes/getting-started-rancher/#install-mysql-database","text":"Note Skip this section if you installed PostgreSQL . This section is only needed if you are willing to use MySQL. To install a quick setup with MySQL as the backend, you need to provide the connection parameters of a fresh setup. For a test setup, you can follow the below instructions: Open a kubectl shell from the top right navigation menu >_ . Run: helm repo add bitnami https://charts.bitnami.com/bitnami helm repo update kubectl create ns gluu #Create gluu namespace Pass in a custom password for the database. Here we used Test1234# . The admin user will be left as root . Notice we are installing in the gluu namespace. Run helm install my-release --set auth.rootPassword=Test1234#,auth.database=jans bitnami/mysql -n gluu","title":"Install MySQL database"},{"location":"admin/recipes/getting-started-rancher/#successful-installation","text":"After the installation is successful, you should have a Statefulset active in the rancher UI as shown in the screenshot below. Install Nginx-Ingress , if you are not using Istio ingress helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx helm repo add stable https://charts.helm.sh/stable helm repo update helm install nginx ingress-nginx/ingress-nginx To get the Loadbalancer IP: kubectl get svc nginx-ingress-nginx-controller --output jsonpath='{.status.loadBalancer.ingress[0].ip}' Install Gluu Flex: Head to Apps --> Charts and search for Gluu Click on Install on the right side of the window. Change the namespace from default to gluu , then click on Next . Scroll through the sections to get familiar with the options. For minimal setup follow with the next instructions. Add License SSA . Before initiating the setup, please obtain an SSA for Flex trial, after which you will issued a JWT. Click on the Persistence section. Change SQL database host uri to postgresql.postgres.svc.cluster.local in the case of PostgreSQL or my-release-mysql.gluu.svc.cluster.local in the case of MySQL . Also set SQL database username , SQL password , and SQL database name to the values you used during the database installation. To enable Casa and the Admin UI, navigate to the Optional Services section and check the Enable casa and boolean flag to enable admin UI boxes. You can also enable different services like Client API and Jackrabbit . Click on the section named Ingress and enable all the endpoints. You might add LB IP or address if you don't have FQDN for Gluu . To pass your FQDN or Domain that is intended to serve the Gluu Flex IDP, head to the Configuration section: Add your FQDN and check the box Is the FQDN globally resolvable . Click on the Edit YAML tab and add your FQDN to nginx-ingress.ingress.hosts and nginx-ingress.ingress.tls.hosts . Click on Install on the bottom right of the window. Note You can upgrade your installation after the deployment. To do that, go to the SUSE Rancher Dashboard -> Apps -> Installed Apps -> gluu -> Click on the 3 dots on the right -> Upgrade -> Make your changes -> Click Update. The running deployment and services of different Gluu Flex components like casa , admin-ui , scim , auth-server , etc can be viewed by navigating through the SUSE Rancher. Go to Workloads and see the running pods. Go under Service Discovery and checkout the Ingresses and Services . All deployed components should be in a healthy and running state like in the screenshot shown below.","title":"Successful Installation"},{"location":"admin/recipes/getting-started-rancher/#connecting-to-the-setup","text":"Note You can skip this section if you have a globally resolvable FQDN . In the event you used microk8s or your fqdn is not registered, the below steps will help with connecting to your setup. To access the setup from a browser or another VM, we need to change the ingress class annotation from kubernetes.io/ingress.class: nginx to kubernetes.io/ingress.class: public e.g., for the specific component you want to access publicly in the browser; Navigate through the SUSE Rancher UI to Service Discovery -> Ingresses Choose the ingress for the targeted component. For example gluu-nginx-ingress-auth-server for auth-server Click on the three dots in the top right corner Click on Edit Yaml On line 8, change the kubernetes.io/ingress.class annotation value from nginx to public Click Save The LoadBalancer IP needs to get mapped inside /etc/hosts with the domain chosen for gluu flex . If the domain you used in the setup is demoexample.gluu.org: 3.65.27.95 demoexample.gluu.org You can do the same edit for every component you want to access publicly from the browser.","title":"Connecting to the Setup"},{"location":"admin/recipes/getting-started-rancher/#testing-configuration-endpoints","text":"Try accessing some Gluu Flex endpoints like https://demoexample.gluu.org/.well-known/openid-configuration in the browser and you'll get back a JSON response; Note that you can also access those endpoints via curl command, E.g. curl -k https://demoexample.gluu.org/.well-known/openid-configuration You should get a similar response like the one below; {\"version\":\"1.1\",\"issuer\":\"https://demoexample.gluu.org\",\"attestation\":{\"base_path\":\"https://demoexample.gluu.org/jans-fido2/restv1/attestation\",\"options_enpoint\":\"https://demoexample.gluu.org/jans-fido2/restv1/attestation/options\",\"result_enpoint\":\"https://demoexample.gluu.org/jans-fido2/restv1/attestation/result\"},\"assertion\":{\"base_path\":\"https://demoexample.gluu.org/jans-fido2/restv1/assertion\",\"options_enpoint\":\"https://demoexample.gluu.org/jans-fido2/restv1/assertion/options\",\"result_enpoint\":\"https://demoexample.gluu.org/jans-fido2/restv1/assertion/result\"}}","title":"Testing Configuration endpoints"},{"location":"admin/recipes/getting-started-rancher/#login-and-add-a-new-user","text":"After inputting the license keys, you can then use admin and the password you set to login to the Admin UI and you should see the Admin UI dashboard. You could also add another test user via the admin UI that will be used for testing Casa and 2FA as shown in the screenshot below. Navigate to Users and click on + in the top right corner to add a user.","title":"Login and Add a New User"},{"location":"admin/recipes/getting-started-rancher/#testing-casa","text":"Jans Casa (\"Casa\") is a self-service web portal for managing account security preferences. The primary use case for Casa is self-service 2FA, but other use cases and functionalities can be supported via Casa plugins. Although you have not enabled two-factor authentication yet, you should still be able to login to Casa as the admin user and the password is the one you set during installation. Point your browser to https://demoexample.gluu.org/jans-casa and you should be welcomed by the Casa login page as shown below. After logging in, you'll be welcomed by the home page as shown below.","title":"Testing Casa"},{"location":"admin/recipes/getting-started-rancher/#enabling-two-factor-authentication","text":"In this part, we are going to enable two standard authentication mechanisms: OTP and FIDO. This can be done through the admin UI. 2FA can be turned on by clicking the switch in the Second Factor Authentication widget. By default, you will be able to choose from a few 2FA policies: Always (upon every login attempt) If the location (e.g. city) detected in the login attempt is unrecognized If the device used to login is unrecognized To reduce the chance of account lockout, enroll at least two different types of 2FA credentials -- e.g. one security key and one OTP app; or one OTP app and one SMS phone number, etc. This way, regardless of which device you're using to access a protected resource, you will have a usable option for passing strong authentication. To enable 2FA, firstly the OTP and FIDO components have to be enabled in the Casa admin UI then login to Casa as an end user, and register an OTP device (i.e. Google Authenticator) and a FIDO device. Register OTP device To add a new OTP token, navigate to 2FA credentials > OTP Tokens. You can either add a soft OTP token by choosing the Soft token option or a hard token by choosing the Hard Token Option Check the soft OTP token and click ready Before proceeding to the next step, Download Google Authenticator from Google Play or Appstore Then proceed and scan the QR code with your app Enter the 6-digit code that appears in your authenticator app and validate the enrollment. Register Fido device To add a new FIDO 2 credential, navigate to 2FA credentials > Security Keys and built-in Platform Authenticators Insert the fido key and click Ready. Casa will prompt you to press the button on the key. Add a nickname and click Add. Once added, the new device will appear in a list on the same page. Click the pencil to edit the device's nickname","title":"Enabling Two-Factor Authentication"},{"location":"admin/recipes/getting-started-rancher/#testing-apache-oidc-locally","text":"In this part, we are going to use docker to locally configure an apache web server, and then install the mod_auth_openidc module and configure it accordingly. Using local docker containers, our approach is to first register a client, then spin up two Apache containers, one serving static content (with server-side includes configured so we can display headers and environment information), and one acting as the OpenID Connect authenticating reverse proxy.","title":"Testing Apache OIDC Locally"},{"location":"admin/recipes/getting-started-rancher/#register-an-openid-connect-client","text":"On the Janssen server, you can register a new client in the Flex Admin UI or the jans-cli. In this section, we are going to show both ways of doing it from the Admin UI and using jans-cli","title":"Register an OpenID Connect client"},{"location":"admin/recipes/getting-started-rancher/#admin-ui","text":"Navigate to Auth server -> Clients and click on + in the top right corner to create a client. Take note of the following keys:values because they configure the right client that we need scopes: email_,openid_,profile responseTypes: code The screenshot below shows an example of the Admin UI section from where a client is created","title":"Admin UI"},{"location":"admin/recipes/getting-started-rancher/#jans-tui","text":"On the Janssen server, we are going to register a new client using the jans-cli. There are two ways you can register an OIDC client with the Janssen server, Manual Client Registration and Dynamic Client Registration (DCR). Here we will use manual client registration. We will use jans-tui tool provided by the Janssen server. jans-tui has a menu-driven interface that makes it easy to configure the Janssen server. Here we will use the menu-driven approach to register a new client. Download jans-cli-tui from the release assets depending on your OS. For example: wget https://github.com/JanssenProject/jans/releases/download/vreplace-janssen-version/jans-cli-tui-linux-ubuntu-X86-64.pyz Now we have jans-cli-tui-linux-ubuntu-X86-64.pyz downloaded. Now we can grab the FQDN, client-id, client-secret, and connect using the following commands: FQDN= #Add your FQDN here TUI_CLIENT_ID=$(kubectl get cm cn -n --template={{.data.tui_client_id}}) TUI_CLIENT_SECRET=$(kubectl get secret cn -n --template={{.data.tui_client_pw}} | base64 -d) #add -noverify if your FQDN is not registered Get schema file using this command python3 jans-cli-tui-linux-ubuntu-X86-64.pyz --host --client-id --client-secret --no-tui --schema /components/schemas/Client Add values for required params and store this JSON in a text file. Take keynote of the following properties. schema-json-file.json { \"dn\": null, \"inum\": null, \"displayName\": \"\", \"clientSecret\": \"\", \"frontChannelLogoutUri\": null, \"frontChannelLogoutSessionRequired\": null, \"registrationAccessToken\": null, \"clientIdIssuedAt\": null, \"clientSecretExpiresAt\": null, \"redirectUris\": [ \"\" ], \"claimRedirectUris\": null, \"responseTypes\": [ \"code\" ], \"grantTypes\": [ \"authorization_code\" ], \"applicationType\": \"web\", \"contacts\": null, \"idTokenTokenBindingCnf\": null, \"logoUri\": null, \"clientUri\": null, \"policyUri\": null, \"tosUri\": null, \"jwksUri\": null, \"jwks\": null, \"sectorIdentifierUri\": null, \"subjectType\": \"public\", \"idTokenSignedResponseAlg\": null, \"idTokenEncryptedResponseAlg\": null, \"idTokenEncryptedResponseEnc\": null, \"userInfoSignedResponseAlg\": null, \"userInfoEncryptedResponseAlg\": null, \"userInfoEncryptedResponseEnc\": null, \"requestObjectSigningAlg\": null, \"requestObjectEncryptionAlg\": null, \"requestObjectEncryptionEnc\": null, \"tokenEndpointAuthMethod\": \"client_secret_basic\", \"tokenEndpointAuthSigningAlg\": null, \"defaultMaxAge\": null, \"requireAuthTime\": null, \"defaultAcrValues\": null, \"initiateLoginUri\": null, \"postLogoutRedirectUris\": null, \"requestUris\": null, \"scopes\": [ \"email\", \"openid\", \"profile\" ], \"claims\": null, \"trustedClient\": false, \"lastAccessTime\": null, \"lastLogonTime\": null, \"persistClientAuthorizations\": null, \"includeClaimsInIdToken\": false, \"refreshTokenLifetime\": null, \"accessTokenLifetime\": null, \"customAttributes\": null, \"customObjectClasses\": null, \"rptAsJwt\": null, \"accessTokenAsJwt\": null, \"accessTokenSigningAlg\": null, \"disabled\": false, \"authorizedOrigins\": null, \"softwareId\": null, \"softwareVersion\": null, \"softwareStatement\": null, \"attributes\": null, \"backchannelTokenDeliveryMode\": null, \"backchannelClientNotificationEndpoint\": null, \"backchannelAuthenticationRequestSigningAlg\": null, \"backchannelUserCodeParameter\": null, \"expirationDate\": null, \"deletable\": false, \"jansId\": null, \"description\": null } Now you can use that JSON file as input to the command below and register your client python3 jans-cli-tui-linux-ubuntu-X86-64.pyz --host --client-id --client-secret --no-tui --operation-id=post-oauth-openid-client --data /schema-json-file.json After the client is successfully registered, there will be data that describes the newly registered client. Some of these values, like inum and clientSecret , will be required before we configure mod_auth_openidc So keep in mind that we shall get back to this.","title":"Jans TUI"},{"location":"admin/recipes/getting-started-rancher/#create-an-application-container","text":"An application docker container will be run locally which will act as the protected resource (PR) / external application. The following files have code for the small application. We shall create a directory locally / on your machine called test and add the required files. Firstly create a project folder named test by running mkdir test && cd test and add the following files with their content; app.conf ServerRoot \"/usr/local/apache2\" Listen 80 LoadModule mpm_event_module modules/mod_mpm_event.so LoadModule authz_core_module modules/mod_authz_core.so LoadModule include_module modules/mod_include.so LoadModule filter_module modules/mod_filter.so LoadModule mime_module modules/mod_mime.so LoadModule log_config_module modules/mod_log_config.so LoadModule setenvif_module modules/mod_setenvif.so LoadModule unixd_module modules/mod_unixd.so LoadModule dir_module modules/mod_dir.so User daemon Group daemon AllowOverride none Require all denied DocumentRoot \"/usr/local/apache2/htdocs\" Options Indexes FollowSymLinks Includes AllowOverride None Require all granted SetEnvIf X-Remote-User \"(.*)\" REMOTE_USER=$0 SetEnvIf X-Remote-User-Name \"(.*)\" REMOTE_USER_NAME=$0 SetEnvIf X-Remote-User-Email \"(.*)\" REMOTE_USER_EMAIL=$0 DirectoryIndex index.html Require all denied ErrorLog /proc/self/fd/2 LogLevel warn LogFormat \"%h %l %u %t \\\"%r\\\" %>s %b \\\"%{Referer}i\\\" \\\"%{User-Agent}i\\\"\" combined LogFormat \"%h %l %u %t \\\"%r\\\" %>s %b\" common CustomLog /proc/self/fd/1 common TypesConfig conf/mime.types AddType application/x-compress .Z AddType application/x-gzip .gz .tgz AddType text/html .shtml AddOutputFilter INCLUDES .shtml user.shtml Hello User

              Hello !

              You authenticated as:

              Your email address is:

              Environment:

              !

              index.html Hello World

              Hello world!

              Dockerfile FROM httpd:2.4.54@sha256:c9eba4494b9d856843b49eb897f9a583a0873b1c14c86d5ab77e5bdedd6ad05d # \"Created\": \"2022-06-08T18:45:46.260791323Z\" , \"Version\":\"2.4.54\" RUN apt-get update \\ && apt-get install -y --no-install-recommends wget ca-certificates libcjose0 libhiredis0.14 apache2-api-20120211 apache2-bin\\ && wget https://github.com/zmartzone/mod_auth_openidc/releases/download/v2.4.11.2/libapache2-mod-auth-openidc_2.4.11.2-1.buster+1_amd64.deb \\ && dpkg -i libapache2-mod-auth-openidc_2.4.11.2-1.buster+1_amd64.deb \\ && ln -s /usr/lib/apache2/modules/mod_auth_openidc.so /usr/local/apache2/modules/mod_auth_openidc.so \\ && rm -rf /var/log/dpkg.log /var/log/alternatives.log /var/log/apt \\ && touch /usr/local/apache2/conf/extra/secret.conf \\ && touch /usr/local/apache2/conf/extra/oidc.conf RUN echo \"\\n\\nLoadModule auth_openidc_module modules/mod_auth_openidc.so\\n\\nInclude conf/extra/secret.conf\\nInclude conf/extra/oidc.conf\\n\" >> /usr/local/apache2/conf/httpd.conf gluu.secret.conf OIDCClientID OIDCCryptoPassphrase OIDCClientSecret OIDCResponseType code OIDCScope \"openid email profile\" OIDCProviderTokenEndpointAuth client_secret_basic OIDCSSLValidateServer Off OIDCRedirectURI http://localhost:8111/oauth2callback OIDCCryptoPassphrase Require valid-user AuthType openid-connect After, run an Apache container which will play the role of an application being protected by the authenticating reverse proxy. docker run -dit -p 8110:80 \\ -v \"$PWD/app.conf\":/usr/local/apache2/conf/httpd.conf \\ -v \"$PWD/index.html\":/usr/local/apache2/htdocs/index.html \\ -v \"$PWD/user.shtml\":/usr/local/apache2/htdocs/user.shtml \\ --name apache-app httpd:2.4 Note that we are using a popular pre-built image useful for acting as a reverse proxy for authentication in front of an application. It contains a stripped-down Apache with minimal modules, and adds the mod_auth_openidc module for performing OpenID Connect authentication. Make a test curl command call to ensure you get back some content as shown in the screenshot below curl http://localhost:8110/user.shtml","title":"Create an Application Container"},{"location":"admin/recipes/getting-started-rancher/#create-an-authenticating-reverse-proxy-container","text":"We shall use Apache, but this time we use a Docker image that has mod_auth_oidc installed and configured. This proxy will require authentication, handle the authentication flow with redirects, and then forward requests to the application. In order to use this, you will need to have registered a new OpenID Connect client on the Janssen server. We did that in the step 1 above Add the following files to the test folder. oidc.conf # Unset to make sure clients can't control these RequestHeader unset X-Remote-User RequestHeader unset X-Remote-User-Name RequestHeader unset X-Remote-User-Email # If you want to see tons of logs for your experimentation #LogLevel trace8 OIDCClientID OIDCProviderMetadataURL https://idp-proxy.med.stanford.edu/auth/realms/med-all/.well-known/openid-configuration #OIDCProviderMetadataURL https://idp-proxy-stage.med.stanford.edu/auth/realms/choir/.well-known/openid-configuration OIDCRedirectURI http://localhost:8111/oauth2callback OIDCScope \"openid email profile\" OIDCRemoteUserClaim principal OIDCPassClaimsAs environment AuthType openid-connect Require valid-user ProxyPass http://app:80/ ProxyPassReverse http://app:80/ RequestHeader set X-Remote-User %{OIDC_CLAIM_principal}e RequestHeader set X-Remote-User-Name %{OIDC_CLAIM_name}e RequestHeader set X-Remote-User-Email %{OIDC_CLAIM_email}e proxy.conf # This is the main Apache HTTP server configuration file. For documentation, see: # http://httpd.apache.org/docs/2.4/ # http://httpd.apache.org/docs/2.4/mod/directives.html # # This is intended to be a hardened configuration, with minimal security surface area necessary # to run mod_auth_openidc. ServerRoot \"/usr/local/apache2\" Listen 80 LoadModule mpm_event_module modules/mod_mpm_event.so LoadModule authn_file_module modules/mod_authn_file.so LoadModule authn_core_module modules/mod_authn_core.so LoadModule authz_host_module modules/mod_authz_host.so LoadModule authz_groupfile_module modules/mod_authz_groupfile.so LoadModule authz_user_module modules/mod_authz_user.so LoadModule authz_core_module modules/mod_authz_core.so LoadModule access_compat_module modules/mod_access_compat.so LoadModule auth_basic_module modules/mod_auth_basic.so LoadModule reqtimeout_module modules/mod_reqtimeout.so LoadModule filter_module modules/mod_filter.so LoadModule mime_module modules/mod_mime.so LoadModule log_config_module modules/mod_log_config.so LoadModule env_module modules/mod_env.so LoadModule headers_module modules/mod_headers.so LoadModule setenvif_module modules/mod_setenvif.so #LoadModule version_module modules/mod_version.so LoadModule proxy_module modules/mod_proxy.so LoadModule proxy_http_module modules/mod_proxy_http.so LoadModule unixd_module modules/mod_unixd.so #LoadModule status_module modules/mod_status.so #LoadModule autoindex_module modules/mod_autoindex.so LoadModule dir_module modules/mod_dir.so LoadModule alias_module modules/mod_alias.so User daemon Group daemon ServerAdmin you@example.com AllowOverride none Require all denied DocumentRoot \"/usr/local/apache2/htdocs\" Options Indexes FollowSymLinks AllowOverride None Require all granted DirectoryIndex index.html Options None Require all denied Require all denied ErrorLog /proc/self/fd/2 LogLevel warn LogFormat \"%h %l %u %t \\\"%r\\\" %>s %b \\\"%{Referer}i\\\" \\\"%{User-Agent}i\\\"\" combined LogFormat \"%h %l %u %t \\\"%r\\\" %>s %b\" common LogFormat \"%h %l %u %t \\\"%r\\\" %>s %b \\\"%{Referer}i\\\" \\\"%{User-Agent}i\\\" %I %O\" combinedio CustomLog /proc/self/fd/1 common ScriptAlias /cgi-bin/ \"/usr/local/apache2/cgi-bin/\" AllowOverride None Options None Require all granted RequestHeader unset Proxy early TypesConfig conf/mime.types AddType application/x-compress .Z AddType application/x-gzip .gz .tgz Include conf/extra/proxy-html.conf SSLRandomSeed startup builtin SSLRandomSeed connect builtin TraceEnable off ServerTokens Prod ServerSignature Off LoadModule auth_openidc_module modules/mod_auth_openidc.so Include conf/extra/secret.conf Include conf/extra/oidc.conf Edit the file to include the client secret for the client you created during DCR, and add a securely generated pass phrase for the session keys docker build --pull -t apache-oidc -f Dockerfile . docker run -dit -p 8111:80 \\ -v \"$PWD/proxy.conf\":/usr/local/apache2/conf/httpd.conf \\ -v \"$PWD/gluu.secret.conf\":/usr/local/apache2/conf/extra/secret.conf \\ -v \"$PWD/oidc.conf\":/usr/local/apache2/conf/extra/oidc.conf \\ --link apache-app:app \\ --name apache-proxy apache-oidc Now open a fresh web browser with private (incognito) mode, and go to this url http://localhost:8111/user.shtml To check the proxy logs docker logs -f apache-proxy To see the app logs docker logs -f apache-app If you modified the configuration files, just restart the proxy. docker restart apache-proxy","title":"Create an Authenticating Reverse Proxy Container"},{"location":"admin/saml/","text":"Where is this content? # The Gluu Flex documentation is a work in progress, and this document is currently a draft. Keep an eye on this page for updates.","title":"Index"},{"location":"admin/saml/#where-is-this-content","text":"The Gluu Flex documentation is a work in progress, and this document is currently a draft. Keep an eye on this page for updates.","title":"Where is this content?"},{"location":"admin/saml/idp/","text":"Where is this content? # The Gluu Flex documentation is a work in progress, and this document is currently a draft. Keep an eye on this page for updates.","title":"Idp"},{"location":"admin/saml/idp/#where-is-this-content","text":"The Gluu Flex documentation is a work in progress, and this document is currently a draft. Keep an eye on this page for updates.","title":"Where is this content?"},{"location":"admin/saml/proxy/","text":"Where is this content? # The Gluu Flex documentation is a work in progress, and this document is currently a draft. Keep an eye on this page for updates.","title":"Proxy"},{"location":"admin/saml/proxy/#where-is-this-content","text":"The Gluu Flex documentation is a work in progress, and this document is currently a draft. Keep an eye on this page for updates.","title":"Where is this content?"},{"location":"includes/cn-system-requirements/","text":"The resources may be set minimally to the below: 8-13 GB RAM based on the services deployed 8-11 CPU cores based on the services deployed 50GB hard-disk Use the listing below for a detailed estimation of the minimum required resources. The table contains the default resources recommendation per service. Depending on the use of each service the resources need may be increase or decrease. Service CPU Unit RAM Disk Space Processor Type Required Auth server 2.5 2.5GB N/A 64 Bit Yes fido2 0.5 0.5GB N/A 64 Bit No scim 1 1GB N/A 64 Bit No config - job 0.3 0.3GB N/A 64 Bit Yes on fresh installs persistence - job 0.3 0.3GB N/A 64 Bit Yes on fresh installs nginx 1 1GB N/A 64 Bit Yes if ALB/Istio not used auth-key-rotation 0.3 0.3GB N/A 64 Bit No [Strongly recommended] config-api 1 1GB N/A 64 Bit No casa 0.5 0.5GB N/A 64 Bit No admin-ui 2 2GB N/A 64 Bit No link 0.5 1GB N/A 64 Bit No saml 0.5 1GB N/A 64 Bit No Releases of images are in style 1.0.0-beta.0, 1.0.0-0","title":"Cn system requirements"},{"location":"install/","tags":["administration","installation"],"text":"Installation Overview # The goal of Gluu Flex is to give you a lot of deployment options. This is a challenge--the more ways to install, the more ways for things to go wrong! But to build a large community, we need to provide ways to install the software in enough different ways to make at least the bulk of the community happy. Currently, that means the following installation options: VM packages for Ubuntu, SUSE and Red Hat Helm deployments for Amazon, Google, Microsoft and Rancher Docker monolith deployment for development / testing (not production) Minimal Configuration # It turns out that just installing the Flex binary object code (i.e. the bits), is totally useless. That's because in order to do anything useful with Gluu Flex, you need a minimal amount of configuration. For example, you need to generate cryptographic key pairs, you need to generate a minimal amount of data in the database, you need to generate some web server TLS certificates. For this reason, for most of the platforms, installation is a three step process. Step 1, install the bits. Step 2, run \"setup\" and answer some basic question (like the hostname of your IDP). Step 3, fire up a configuration tool to perform any other last mile configuration. Databases # Gluu Flex gives you a few options to store data: MySQL, Postgres, Couchbase, Amazon Aurora, and Spanner. You can also configure an in-memory cache server like Redis. Sometimes installation and configuration of this database is included in the setup process. Sometimes, you need to setup the database ahead of time. Please refer to the database instructions specific for your choice. And of course, you may need to refer to the database documentation itself--we don't want to duplicate any of that third party content. Optimization # Remember, installation is just a starting point. To get peak performance, you may need to tweak some of the configuration dials for your system or the database. If you intend to deploy a Gluu Flex in production for high concurrency, make sure you benchmark the exact flows you expect to serve in production.","title":"Installation Overview"},{"location":"install/#installation-overview","text":"The goal of Gluu Flex is to give you a lot of deployment options. This is a challenge--the more ways to install, the more ways for things to go wrong! But to build a large community, we need to provide ways to install the software in enough different ways to make at least the bulk of the community happy. Currently, that means the following installation options: VM packages for Ubuntu, SUSE and Red Hat Helm deployments for Amazon, Google, Microsoft and Rancher Docker monolith deployment for development / testing (not production)","title":"Installation Overview"},{"location":"install/#minimal-configuration","text":"It turns out that just installing the Flex binary object code (i.e. the bits), is totally useless. That's because in order to do anything useful with Gluu Flex, you need a minimal amount of configuration. For example, you need to generate cryptographic key pairs, you need to generate a minimal amount of data in the database, you need to generate some web server TLS certificates. For this reason, for most of the platforms, installation is a three step process. Step 1, install the bits. Step 2, run \"setup\" and answer some basic question (like the hostname of your IDP). Step 3, fire up a configuration tool to perform any other last mile configuration.","title":"Minimal Configuration"},{"location":"install/#databases","text":"Gluu Flex gives you a few options to store data: MySQL, Postgres, Couchbase, Amazon Aurora, and Spanner. You can also configure an in-memory cache server like Redis. Sometimes installation and configuration of this database is included in the setup process. Sometimes, you need to setup the database ahead of time. Please refer to the database instructions specific for your choice. And of course, you may need to refer to the database documentation itself--we don't want to duplicate any of that third party content.","title":"Databases"},{"location":"install/#optimization","text":"Remember, installation is just a starting point. To get peak performance, you may need to tweak some of the configuration dials for your system or the database. If you intend to deploy a Gluu Flex in production for high concurrency, make sure you benchmark the exact flows you expect to serve in production.","title":"Optimization"},{"location":"install/agama/prerequisites/","tags":["administration","installation"],"text":"Agama Lab # Agama Lab is a platform to manage your Gluu license. This is where you may subscribe to Gluu Flex or obtain credentials for your enterprise license. To begin, please visit Agama Lab You may register via email or login via GitHub If you want to author or test Agama projects, you will need to login via GitHub Once you have logged in, please navigate to Market > SCAN and subscribe to the free tier. SCAN is the API gateway Gluu uses to validate licenses. The free tier will give you 500 credits. As license calls do not cost credits, this will not cost you anything. Software Statement Assertions # In order to install Flex, you will need a Software Statement Assertion (SSA). An SSA is a signed JSON Web Token (JWT) that is required by the Flex install script to validate your license. Obtaining an SSA # Gluu issues SSAs through the Agama Lab web interface. You can obtain an SSA for use with Flex by following these steps: Login to Agama Lab On the left navigation bar, select Market Navigate to the tab named SSA . Sign up for a free SCAN subscription, which will give you 500 SCAN credits. Flex does not cost any SCAN credits, so you will not be charged for SCAN. Click on Create New SSA On Software Name , fill in a unique identifier for this SSA Description is optional Under Software Roles , tick license Under Expiration Date , select an appropriate date. Your SSA will not be useable after that date. Under SSA Lifetime , choose an appropriate lifetime for the Flex client. One month or longer is recommended. Deselect One time use and Rotate SSA Click Create - Click on Detail of the newly issued SSA, then click on Show JWT You will be shown a long string of characters. Copy this and save it to a file. You may now use this file during Flex installation. License # Gluu Flex uses the SSA obtained in the above step to either request a 30 day trial license or verify presence of a license tied to your Agama Lab account. One account may request one trial license in its lifetime. To purchase a full license, please navigate to the Flex tab of the marketplace where you may purchase licenses for up to 1600 MAU (monthly active users). To purchase an enterprise license for more MAU, please contact Sales . If you have subscribed to Flex via Agama Lab, the SSA obtained in the step before will automatically link your license to your installation. For enterprise licenses, please open a support ticket so that we can issue a license against your Agama account. Once this is done, you may use the SSA obtained to proceed to installation.","title":"Prerequisites"},{"location":"install/agama/prerequisites/#agama-lab","text":"Agama Lab is a platform to manage your Gluu license. This is where you may subscribe to Gluu Flex or obtain credentials for your enterprise license. To begin, please visit Agama Lab You may register via email or login via GitHub If you want to author or test Agama projects, you will need to login via GitHub Once you have logged in, please navigate to Market > SCAN and subscribe to the free tier. SCAN is the API gateway Gluu uses to validate licenses. The free tier will give you 500 credits. As license calls do not cost credits, this will not cost you anything.","title":"Agama Lab"},{"location":"install/agama/prerequisites/#software-statement-assertions","text":"In order to install Flex, you will need a Software Statement Assertion (SSA). An SSA is a signed JSON Web Token (JWT) that is required by the Flex install script to validate your license.","title":"Software Statement Assertions"},{"location":"install/agama/prerequisites/#obtaining-an-ssa","text":"Gluu issues SSAs through the Agama Lab web interface. You can obtain an SSA for use with Flex by following these steps: Login to Agama Lab On the left navigation bar, select Market Navigate to the tab named SSA . Sign up for a free SCAN subscription, which will give you 500 SCAN credits. Flex does not cost any SCAN credits, so you will not be charged for SCAN. Click on Create New SSA On Software Name , fill in a unique identifier for this SSA Description is optional Under Software Roles , tick license Under Expiration Date , select an appropriate date. Your SSA will not be useable after that date. Under SSA Lifetime , choose an appropriate lifetime for the Flex client. One month or longer is recommended. Deselect One time use and Rotate SSA Click Create - Click on Detail of the newly issued SSA, then click on Show JWT You will be shown a long string of characters. Copy this and save it to a file. You may now use this file during Flex installation.","title":"Obtaining an SSA"},{"location":"install/agama/prerequisites/#license","text":"Gluu Flex uses the SSA obtained in the above step to either request a 30 day trial license or verify presence of a license tied to your Agama Lab account. One account may request one trial license in its lifetime. To purchase a full license, please navigate to the Flex tab of the marketplace where you may purchase licenses for up to 1600 MAU (monthly active users). To purchase an enterprise license for more MAU, please contact Sales . If you have subscribed to Flex via Agama Lab, the SSA obtained in the step before will automatically link your license to your installation. For enterprise licenses, please open a support ticket so that we can issue a license against your Agama account. Once this is done, you may use the SSA obtained to proceed to installation.","title":"License"},{"location":"install/docker-install/compose/","tags":["administration","reference","kubernetes","docker image","docker compose"],"text":"Warning This image is for testing and development purposes only. Use Flex helm charts for production setups. Overview # Docker monolith image packaging for Gluu Flex. This image packs janssen services including the auth-server, config-api, fido2, casa, scim and the Gluu admin ui. Pre-requisites # Docker Docker compose Versions # See Releases for stable versions. This image should never be used in production. For bleeding-edge/unstable version, use gluufederation/monolith:5.0.0_dev . Environment Variables # Installation depends on the set of environment variables shown below. These environment variables can be set to customize installation as per the need. If not set, the installer uses default values. ENV Description Default CN_HOSTNAME Hostname to install gluu with. demoexample.gluu.org CN_ADMIN_PASS Password of the admin user. 1t5Fin3#security CN_ORG_NAME Organization name. Used for ssl cert generation. Gluu CN_EMAIL Email. Used for ssl cert generation. team@gluu.org CN_CITY City. Used for ssl cert generation. Austin CN_STATE State. Used for ssl cert generation TX CN_COUNTRY Country. Used for ssl cert generation. US CN_INSTALL_MYSQL Install gluu with mysql as the backend false CN_INSTALL_PGSQL Install gluu with Postgres as the backend false CN_INSTALL_ADMIN_UI Installs the Admin-UI true CN_INSTALL_CONFIG_API Installs the Config API service. true CN_INSTALL_SCIM Installs the SCIM API service. true CN_INSTALL_FIDO2 Installs the FIDO2 API service. true RDBMS_DATABASE RDBMS gluu database for MySQL or Postgres. gluu RDBMS_USER RDBMS database user for MySQL or Postgres. gluu RDBMS_PASSWORD RDBMS database user password for MySQL or Postgres. 1t5Fin3#security RDBMS_HOST RDBMS host for MySQL or Postgres. mysql which is the docker compose service name TEST_CLIENT_ID ID of test client in UUID which has all available scopes to access any gluu API 9876baac-de39-4c23-8a78-674b59df8c09 TEST_CLIENT_SECRET Secret for test client 1t5Fin3#security TEST_CLIENT_TRUSTED Trust test client true TEST_CLIENT_REDIRECT_URI Not Implemented yet Redirect URI for test client. Multiple uri's with comma may be provided, if not provided redirect uris will be same as the config-api-client `` How to run # Download the compose file of your chosen persistence from mysql or postgres wget https://raw.githubusercontent.com/GluuFederation/flex/main/docker-flex-monolith/flex-mysql-compose.yml wget https://raw.githubusercontent.com/GluuFederation/flex/main/docker-flex-monolith/flex-postgres-compose.yml Download the script files wget https://raw.githubusercontent.com/GluuFederation/flex/main/docker-flex-monolith/up.sh wget https://raw.githubusercontent.com/GluuFederation/flex/main/docker-flex-monolith/down.sh wget https://raw.githubusercontent.com/GluuFederation/flex/main/docker-flex-monolith/clean.sh Give execute permission to the scripts chmod u+x up.sh down.sh clean.sh This docker compose file runs two containers, the flex monolith container and mysql container. To start the containers. ./up.sh #You can pass mysql|postgres as an argument to the script. If you don't pass any, it will default to mysql. To view the containers running docker compose -f flex-mysql-compose.yml ps To stop the containers. ./down.sh #You can pass mysql|postgres as an argument to the script. If you don't pass any, it will default to mysql. Configure Gluu flex # Access the Docker container shell using: docker compose -f flex-mysql-compose.yml exec flex /bin/bash #This opens a bash terminal in the running container You can grab client_id and client_pw (secret), and other values from setup.properties or /opt/jans/jans-setup/setup.properties.last Use the CLI tools located under /opt/jans/jans-cli/ to configure Gluu flex as needed. For example you can run the TUI : python3 /opt/jans/jans-cli/config-cli-tui.py Access endpoints externally # Add to your /etc/hosts file the ip domain record which should be the ip of the instance docker is installed at and the domain used in the env above CN_HOSTNAME . # For-example 172 .22.0.3 demoexample.gluu.org After adding the record you can hit endpoints such as https://demoexample.gluu.org/.well-known/openid-configuration Clean up # Remove setup and volumes ./clean.sh #You can pass mysql|postgres as an argument to the script. If you don't pass any, it will default to mysql.","title":"Docker compose"},{"location":"install/docker-install/compose/#overview","text":"Docker monolith image packaging for Gluu Flex. This image packs janssen services including the auth-server, config-api, fido2, casa, scim and the Gluu admin ui.","title":"Overview"},{"location":"install/docker-install/compose/#pre-requisites","text":"Docker Docker compose","title":"Pre-requisites"},{"location":"install/docker-install/compose/#versions","text":"See Releases for stable versions. This image should never be used in production. For bleeding-edge/unstable version, use gluufederation/monolith:5.0.0_dev .","title":"Versions"},{"location":"install/docker-install/compose/#environment-variables","text":"Installation depends on the set of environment variables shown below. These environment variables can be set to customize installation as per the need. If not set, the installer uses default values. ENV Description Default CN_HOSTNAME Hostname to install gluu with. demoexample.gluu.org CN_ADMIN_PASS Password of the admin user. 1t5Fin3#security CN_ORG_NAME Organization name. Used for ssl cert generation. Gluu CN_EMAIL Email. Used for ssl cert generation. team@gluu.org CN_CITY City. Used for ssl cert generation. Austin CN_STATE State. Used for ssl cert generation TX CN_COUNTRY Country. Used for ssl cert generation. US CN_INSTALL_MYSQL Install gluu with mysql as the backend false CN_INSTALL_PGSQL Install gluu with Postgres as the backend false CN_INSTALL_ADMIN_UI Installs the Admin-UI true CN_INSTALL_CONFIG_API Installs the Config API service. true CN_INSTALL_SCIM Installs the SCIM API service. true CN_INSTALL_FIDO2 Installs the FIDO2 API service. true RDBMS_DATABASE RDBMS gluu database for MySQL or Postgres. gluu RDBMS_USER RDBMS database user for MySQL or Postgres. gluu RDBMS_PASSWORD RDBMS database user password for MySQL or Postgres. 1t5Fin3#security RDBMS_HOST RDBMS host for MySQL or Postgres. mysql which is the docker compose service name TEST_CLIENT_ID ID of test client in UUID which has all available scopes to access any gluu API 9876baac-de39-4c23-8a78-674b59df8c09 TEST_CLIENT_SECRET Secret for test client 1t5Fin3#security TEST_CLIENT_TRUSTED Trust test client true TEST_CLIENT_REDIRECT_URI Not Implemented yet Redirect URI for test client. Multiple uri's with comma may be provided, if not provided redirect uris will be same as the config-api-client ``","title":"Environment Variables"},{"location":"install/docker-install/compose/#how-to-run","text":"Download the compose file of your chosen persistence from mysql or postgres wget https://raw.githubusercontent.com/GluuFederation/flex/main/docker-flex-monolith/flex-mysql-compose.yml wget https://raw.githubusercontent.com/GluuFederation/flex/main/docker-flex-monolith/flex-postgres-compose.yml Download the script files wget https://raw.githubusercontent.com/GluuFederation/flex/main/docker-flex-monolith/up.sh wget https://raw.githubusercontent.com/GluuFederation/flex/main/docker-flex-monolith/down.sh wget https://raw.githubusercontent.com/GluuFederation/flex/main/docker-flex-monolith/clean.sh Give execute permission to the scripts chmod u+x up.sh down.sh clean.sh This docker compose file runs two containers, the flex monolith container and mysql container. To start the containers. ./up.sh #You can pass mysql|postgres as an argument to the script. If you don't pass any, it will default to mysql. To view the containers running docker compose -f flex-mysql-compose.yml ps To stop the containers. ./down.sh #You can pass mysql|postgres as an argument to the script. If you don't pass any, it will default to mysql.","title":"How to run"},{"location":"install/docker-install/compose/#configure-gluu-flex","text":"Access the Docker container shell using: docker compose -f flex-mysql-compose.yml exec flex /bin/bash #This opens a bash terminal in the running container You can grab client_id and client_pw (secret), and other values from setup.properties or /opt/jans/jans-setup/setup.properties.last Use the CLI tools located under /opt/jans/jans-cli/ to configure Gluu flex as needed. For example you can run the TUI : python3 /opt/jans/jans-cli/config-cli-tui.py","title":"Configure Gluu flex"},{"location":"install/docker-install/compose/#access-endpoints-externally","text":"Add to your /etc/hosts file the ip domain record which should be the ip of the instance docker is installed at and the domain used in the env above CN_HOSTNAME . # For-example 172 .22.0.3 demoexample.gluu.org After adding the record you can hit endpoints such as https://demoexample.gluu.org/.well-known/openid-configuration","title":"Access endpoints externally"},{"location":"install/docker-install/compose/#clean-up","text":"Remove setup and volumes ./clean.sh #You can pass mysql|postgres as an argument to the script. If you don't pass any, it will default to mysql.","title":"Clean up"},{"location":"install/docker-install/quick-start/","tags":["administration","installation","quick-start","docker"],"text":"Warning This image is for testing and development purposes only. Use Flex helm charts for production setups. Overview # The quickest way to get Gluu flex up and running is to have a Docker container-based deployment. System Requirements # System should meet minimum VM system requirements Install # Installation depends on a set of environment variables . These environment variables can be set to customize installation as per the need. If not set, the installer uses default values. Run this command to start the installation: wget https://raw.githubusercontent.com/GluuFederation/flex/vreplace-flex-version/automation/startflexmonolithdemo.sh && chmod u+x startflexmonolithdemo.sh && sudo bash startflexmonolithdemo.sh demoexample.gluu.org MYSQL Console messages like below confirms the successful installation: [+] Running 3/3 \u283f Network docker-flex-monolith_cloud_bridge Created 0.0s \u283f Container docker-flex-monolith-mysql-1 Started 0.6s \u283f Container docker-flex-monolith-flex-1 Started 0.9s Waiting for auth-server to come up. Depending on the resources it may take 3-5 mins for the services to be up. Testing openid-configuration endpoint.. As can be seen, the install script also accesses the well-known endpoints to verify that Gluu Flex is responsive. Verify Installation By Accessing Standard Endpoints # To access Gluu flex standard endpoints from outside of the Docker container, systems /etc/hosts file needs to be updated. Open the file and add the IP domain record which should be the IP of the instance docker is installed. And the domain used in the env above CN_HOSTNAME . # For-example 172 .22.0.3 demoexample.gluu.org After adding the record, hit the standard endpoints such as https://demoexample.gluu.org/.well-known/openid-configuration Configure Gluu flex # Access the Docker container shell using: docker exec -ti docker-flex-monolith-flex-1 bash Grab a pair of client_id and client_pw(secret) from setup.properties or /opt/jans/jans-setup/setup.properties.last Use the CLI tools located under /opt/jans/jans-cli/ to configure Gluu flex as needed. For example you can run the TUI : python3 /opt/jans/jans-cli/config-cli-tui.py Uninstall/Remove Gluu flex # This docker based installation uses docker compose under the hood to create containers. Hence uninstalling Gluu flex involves invoking docker compose with appropriate yml file. Run command below to stop and remove containers. docker compose -f /tmp/flex/docker-flex-monolith/flex-mysql-compose.yml down && rm -rf flex-* Console messages like below confirms the successful removal: [+] Running 3/3 \u283f Container docker-flex-monolith-flex-1 Removed 10.5s \u283f Container docker-flex-monolith-mysql-1 Removed 0.9s \u283f Network docker-flex-monolith_cloud_bridge Removed 0.1s","title":"Quick Start"},{"location":"install/docker-install/quick-start/#overview","text":"The quickest way to get Gluu flex up and running is to have a Docker container-based deployment.","title":"Overview"},{"location":"install/docker-install/quick-start/#system-requirements","text":"System should meet minimum VM system requirements","title":"System Requirements"},{"location":"install/docker-install/quick-start/#install","text":"Installation depends on a set of environment variables . These environment variables can be set to customize installation as per the need. If not set, the installer uses default values. Run this command to start the installation: wget https://raw.githubusercontent.com/GluuFederation/flex/vreplace-flex-version/automation/startflexmonolithdemo.sh && chmod u+x startflexmonolithdemo.sh && sudo bash startflexmonolithdemo.sh demoexample.gluu.org MYSQL Console messages like below confirms the successful installation: [+] Running 3/3 \u283f Network docker-flex-monolith_cloud_bridge Created 0.0s \u283f Container docker-flex-monolith-mysql-1 Started 0.6s \u283f Container docker-flex-monolith-flex-1 Started 0.9s Waiting for auth-server to come up. Depending on the resources it may take 3-5 mins for the services to be up. Testing openid-configuration endpoint.. As can be seen, the install script also accesses the well-known endpoints to verify that Gluu Flex is responsive.","title":"Install"},{"location":"install/docker-install/quick-start/#verify-installation-by-accessing-standard-endpoints","text":"To access Gluu flex standard endpoints from outside of the Docker container, systems /etc/hosts file needs to be updated. Open the file and add the IP domain record which should be the IP of the instance docker is installed. And the domain used in the env above CN_HOSTNAME . # For-example 172 .22.0.3 demoexample.gluu.org After adding the record, hit the standard endpoints such as https://demoexample.gluu.org/.well-known/openid-configuration","title":"Verify Installation By Accessing Standard Endpoints"},{"location":"install/docker-install/quick-start/#configure-gluu-flex","text":"Access the Docker container shell using: docker exec -ti docker-flex-monolith-flex-1 bash Grab a pair of client_id and client_pw(secret) from setup.properties or /opt/jans/jans-setup/setup.properties.last Use the CLI tools located under /opt/jans/jans-cli/ to configure Gluu flex as needed. For example you can run the TUI : python3 /opt/jans/jans-cli/config-cli-tui.py","title":"Configure Gluu flex"},{"location":"install/docker-install/quick-start/#uninstallremove-gluu-flex","text":"This docker based installation uses docker compose under the hood to create containers. Hence uninstalling Gluu flex involves invoking docker compose with appropriate yml file. Run command below to stop and remove containers. docker compose -f /tmp/flex/docker-flex-monolith/flex-mysql-compose.yml down && rm -rf flex-* Console messages like below confirms the successful removal: [+] Running 3/3 \u283f Container docker-flex-monolith-flex-1 Removed 10.5s \u283f Container docker-flex-monolith-mysql-1 Removed 0.9s \u283f Network docker-flex-monolith_cloud_bridge Removed 0.1s","title":"Uninstall/Remove Gluu flex"},{"location":"install/helm-install/","tags":["administration","installation","helm"],"text":"Overview # Gluu Flex enables organizations to build a scalable centralized authentication and authorization service using free open source software. The components of the project include client and server implementations of the OAuth, OpenID Connect, SCIM and FIDO standards. All these components are deployed using Gluu helm chart . You can check the reference guide to view the list of the chart components and values. Looking for older helm charts? # If you are looking for older helm charts, you need to build them from the Gluu Flex repository. We only keep the last 5 versions of the chart up. We support auto-upgrade using helm upgrade and hence want everyone to stay up to date with our charts. To build older charts manually from the Gluu Flex repository, you can use the following example which assumes we are building for janssen version v5.0.0 : git clone --filter blob:none --no-checkout https://github.com/GluuFederation/flex.git /tmp/flex \\ && cd /tmp/flex \\ && git sparse-checkout init --cone \\ && git checkout v5.0.0 \\ && git sparse-checkout add charts/gluu \\ && cd charts/gluu \\ && helm dependency update \\ && helm package .","title":"Overview"},{"location":"install/helm-install/#overview","text":"Gluu Flex enables organizations to build a scalable centralized authentication and authorization service using free open source software. The components of the project include client and server implementations of the OAuth, OpenID Connect, SCIM and FIDO standards. All these components are deployed using Gluu helm chart . You can check the reference guide to view the list of the chart components and values.","title":"Overview"},{"location":"install/helm-install/#looking-for-older-helm-charts","text":"If you are looking for older helm charts, you need to build them from the Gluu Flex repository. We only keep the last 5 versions of the chart up. We support auto-upgrade using helm upgrade and hence want everyone to stay up to date with our charts. To build older charts manually from the Gluu Flex repository, you can use the following example which assumes we are building for janssen version v5.0.0 : git clone --filter blob:none --no-checkout https://github.com/GluuFederation/flex.git /tmp/flex \\ && cd /tmp/flex \\ && git sparse-checkout init --cone \\ && git checkout v5.0.0 \\ && git sparse-checkout add charts/gluu \\ && cd charts/gluu \\ && helm dependency update \\ && helm package .","title":"Looking for older helm charts?"},{"location":"install/helm-install/amazon-eks/","tags":["administration","installation","helm","EKS","Amazon Web Services","AWS"],"text":"Install Gluu Flex on EKS # System Requirements # The resources may be set minimally to the below: 8-13 GB RAM based on the services deployed 8-11 CPU cores based on the services deployed 50GB hard-disk Use the listing below for a detailed estimation of the minimum required resources. The table contains the default resources recommendation per service. Depending on the use of each service the resources need may be increase or decrease. Service CPU Unit RAM Disk Space Processor Type Required Auth server 2.5 2.5GB N/A 64 Bit Yes fido2 0.5 0.5GB N/A 64 Bit No scim 1 1GB N/A 64 Bit No config - job 0.3 0.3GB N/A 64 Bit Yes on fresh installs persistence - job 0.3 0.3GB N/A 64 Bit Yes on fresh installs nginx 1 1GB N/A 64 Bit Yes if ALB/Istio not used auth-key-rotation 0.3 0.3GB N/A 64 Bit No [Strongly recommended] config-api 1 1GB N/A 64 Bit No casa 0.5 0.5GB N/A 64 Bit No admin-ui 2 2GB N/A 64 Bit No link 0.5 1GB N/A 64 Bit No saml 0.5 1GB N/A 64 Bit No Releases of images are in style 1.0.0-beta.0, 1.0.0-0 Initial Setup # Before initiating the setup, please obtain an SSA for Flex trial, after which you will issued a JWT. Install aws cli Configure your AWS user account using aws configure command. This makes you able to authenticate before creating the cluster. Note that this user account must have permissions to work with Amazon EKS IAM roles and service linked roles, AWS CloudFormation, and a VPC and related resources Install kubectl Install eksctl Create cluster using eksctl such as the following example: eksctl create cluster --name gluu-cluster --nodegroup-name gluu-nodes --node-type NODE_TYPE --nodes 2 --managed --region REGION_CODE You can adjust node-type and nodes number as per your desired cluster size To be able to attach volumes to your pod, you need to install the Amazon EBS CSI driver Install Helm3 Create gluu namespace where our resources will reside kubectl create namespace gluu Gluu Flex Installation using Helm # Install Nginx-Ingress , if you are not using Istio ingress helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx helm repo add stable https://charts.helm.sh/stable helm repo update helm install nginx ingress-nginx/ingress-nginx Create a file named override.yaml and add changes as per your desired configuration: FQDN/domain is not registered: Get the Loadbalancer address: kubectl get svc nginx-ingress-nginx-controller --output jsonpath='{.status.loadBalancer.ingress[0].hostname}' Add the following yaml snippet to your override.yaml file: global : isFqdnRegistered : false config : configmap : lbAddr : http:// #Add LB address from previous command FQDN/domain is registered: Add the following yaml snippet to your override.yaml file: global : isFqdnRegistered : true fqdn : demoexample.gluu.org #CHANGE-THIS to the FQDN used for Gluu config : configmap : lbAddr : http:// #Add LB address from previous command nginx : ingress : enabled : true path : / hosts : - demoexample.gluu.org #CHANGE-THIS to the FQDN used for Gluu tls : - secretName : tls-certificate hosts : - demoexample.gluu.org #CHANGE-THIS to the FQDN used for Gluu Couchbase for pesistence storage Add the following yaml snippet to your override.yaml file: global : cnPersistenceType : couchbase config : configmap : # The prefix of couchbase buckets. This helps with separation in between different environments and allows for the same couchbase cluster to be used by different setups of Janssen. cnCouchbaseBucketPrefix : jans # -- Couchbase certificate authority string. This must be encoded using base64. This can also be found in your couchbase UI Security > Root Certificate. In mTLS setups this is not required. cnCouchbaseCrt : SWFtTm90YVNlcnZpY2VBY2NvdW50Q2hhbmdlTWV0b09uZQo= # -- The number of replicas per index created. Please note that the number of index nodes must be one greater than the number of index replicas. That means if your couchbase cluster only has 2 index nodes you cannot place the number of replicas to be higher than 1. cnCouchbaseIndexNumReplica : 0 # -- Couchbase password for the restricted user config.configmap.cnCouchbaseUser that is often used inside the services. The password must contain one digit, one uppercase letter, one lower case letter and one symbol cnCouchbasePassword : P@ssw0rd # -- The Couchbase super user (admin) username. This user is used during initialization only. cnCouchbaseSuperUser : admin # -- Couchbase password for the superuser config.configmap.cnCouchbaseSuperUser that is used during the initialization process. The password must contain one digit, one uppercase letter, one lower case letter and one symbol cnCouchbaseSuperUserPassword : Test1234# # -- Couchbase URL. This should be in FQDN format for either remote or local Couchbase clusters. The address can be an internal address inside the kubernetes cluster cnCouchbaseUrl : cbjanssen.default.svc.cluster.local # -- Couchbase restricted user cnCouchbaseUser : janssen PostgreSQL for persistence storage In a production environment, a production grade PostgreSQL server should be used such as Amazon RDS For testing purposes, you can deploy it on the EKS cluster using the following command: helm install my-release --set auth.postgresPassword=Test1234#,auth.database=gluu -n gluu oci://registry-1.docker.io/bitnamicharts/postgresql Add the following yaml snippet to your override.yaml file: global : cnPersistenceType : sql config : configmap : cnSqlDbName : gluu cnSqlDbPort : 5432 cnSqlDbDialect : pgsql cnSqlDbHost : my-release-postgresql.gluu.svc cnSqlDbUser : postgres cnSqlDbTimezone : UTC cnSqldbUserPassword : Test1234# MySQL for persistence storage In a production environment, a production grade MySQL server should be used such as Amazon RDS For testing purposes, you can deploy it on the EKS cluster using the following command: helm install my-release --set auth.rootPassword=Test1234#,auth.database=gluu -n gluu oci://registry-1.docker.io/bitnamicharts/mysql Add the following yaml snippet to your override.yaml file: global : cnPersistenceType : sql config : configmap : cnSqlDbName : gluu cnSqlDbPort : 3306 cnSqlDbDialect : mysql cnSqlDbHost : my-release-mysql.gluu.svc cnSqlDbUser : root cnSqlDbTimezone : UTC cnSqldbUserPassword : Test1234# So if your desired configuration has FQDN and MySQL, the final override.yaml file will look something like that: global : cnPersistenceType : sql isFqdnRegistered : true fqdn : demoexample.gluu.org #CHANGE-THIS to the FQDN used for Gluu nginx-ingress : ingress : path : / hosts : - demoexample.gluu.org #CHANGE-THIS to the FQDN used for Gluu tls : - secretName : tls-certificate hosts : - demoexample.gluu.org #CHANGE-THIS to the FQDN used for Gluu config : configmap : lbAddr : http:// #Add LB address from previous command cnSqlDbName : gluu cnSqlDbPort : 3306 cnSqlDbDialect : mysql cnSqlDbHost : my-release-mysql.gluu.svc cnSqlDbUser : root cnSqlDbTimezone : UTC cnSqldbUserPassword : Test1234# Install Gluu Flex After finishing all the tweaks to the override.yaml file, we can use it to install gluu flex. helm repo add gluu-flex https://docs.gluu.org/charts helm repo update helm install gluu gluu-flex/gluu -n gluu -f override.yaml Configure Gluu Flex # You can use the Janssen TUI to configure Flex components. The TUI calls the Config API to perform ad hoc configuration.","title":"Amazon EKS"},{"location":"install/helm-install/amazon-eks/#install-gluu-flex-on-eks","text":"","title":"Install Gluu Flex on EKS"},{"location":"install/helm-install/amazon-eks/#system-requirements","text":"The resources may be set minimally to the below: 8-13 GB RAM based on the services deployed 8-11 CPU cores based on the services deployed 50GB hard-disk Use the listing below for a detailed estimation of the minimum required resources. The table contains the default resources recommendation per service. Depending on the use of each service the resources need may be increase or decrease. Service CPU Unit RAM Disk Space Processor Type Required Auth server 2.5 2.5GB N/A 64 Bit Yes fido2 0.5 0.5GB N/A 64 Bit No scim 1 1GB N/A 64 Bit No config - job 0.3 0.3GB N/A 64 Bit Yes on fresh installs persistence - job 0.3 0.3GB N/A 64 Bit Yes on fresh installs nginx 1 1GB N/A 64 Bit Yes if ALB/Istio not used auth-key-rotation 0.3 0.3GB N/A 64 Bit No [Strongly recommended] config-api 1 1GB N/A 64 Bit No casa 0.5 0.5GB N/A 64 Bit No admin-ui 2 2GB N/A 64 Bit No link 0.5 1GB N/A 64 Bit No saml 0.5 1GB N/A 64 Bit No Releases of images are in style 1.0.0-beta.0, 1.0.0-0","title":"System Requirements"},{"location":"install/helm-install/amazon-eks/#initial-setup","text":"Before initiating the setup, please obtain an SSA for Flex trial, after which you will issued a JWT. Install aws cli Configure your AWS user account using aws configure command. This makes you able to authenticate before creating the cluster. Note that this user account must have permissions to work with Amazon EKS IAM roles and service linked roles, AWS CloudFormation, and a VPC and related resources Install kubectl Install eksctl Create cluster using eksctl such as the following example: eksctl create cluster --name gluu-cluster --nodegroup-name gluu-nodes --node-type NODE_TYPE --nodes 2 --managed --region REGION_CODE You can adjust node-type and nodes number as per your desired cluster size To be able to attach volumes to your pod, you need to install the Amazon EBS CSI driver Install Helm3 Create gluu namespace where our resources will reside kubectl create namespace gluu","title":"Initial Setup"},{"location":"install/helm-install/amazon-eks/#gluu-flex-installation-using-helm","text":"Install Nginx-Ingress , if you are not using Istio ingress helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx helm repo add stable https://charts.helm.sh/stable helm repo update helm install nginx ingress-nginx/ingress-nginx Create a file named override.yaml and add changes as per your desired configuration: FQDN/domain is not registered: Get the Loadbalancer address: kubectl get svc nginx-ingress-nginx-controller --output jsonpath='{.status.loadBalancer.ingress[0].hostname}' Add the following yaml snippet to your override.yaml file: global : isFqdnRegistered : false config : configmap : lbAddr : http:// #Add LB address from previous command FQDN/domain is registered: Add the following yaml snippet to your override.yaml file: global : isFqdnRegistered : true fqdn : demoexample.gluu.org #CHANGE-THIS to the FQDN used for Gluu config : configmap : lbAddr : http:// #Add LB address from previous command nginx : ingress : enabled : true path : / hosts : - demoexample.gluu.org #CHANGE-THIS to the FQDN used for Gluu tls : - secretName : tls-certificate hosts : - demoexample.gluu.org #CHANGE-THIS to the FQDN used for Gluu Couchbase for pesistence storage Add the following yaml snippet to your override.yaml file: global : cnPersistenceType : couchbase config : configmap : # The prefix of couchbase buckets. This helps with separation in between different environments and allows for the same couchbase cluster to be used by different setups of Janssen. cnCouchbaseBucketPrefix : jans # -- Couchbase certificate authority string. This must be encoded using base64. This can also be found in your couchbase UI Security > Root Certificate. In mTLS setups this is not required. cnCouchbaseCrt : SWFtTm90YVNlcnZpY2VBY2NvdW50Q2hhbmdlTWV0b09uZQo= # -- The number of replicas per index created. Please note that the number of index nodes must be one greater than the number of index replicas. That means if your couchbase cluster only has 2 index nodes you cannot place the number of replicas to be higher than 1. cnCouchbaseIndexNumReplica : 0 # -- Couchbase password for the restricted user config.configmap.cnCouchbaseUser that is often used inside the services. The password must contain one digit, one uppercase letter, one lower case letter and one symbol cnCouchbasePassword : P@ssw0rd # -- The Couchbase super user (admin) username. This user is used during initialization only. cnCouchbaseSuperUser : admin # -- Couchbase password for the superuser config.configmap.cnCouchbaseSuperUser that is used during the initialization process. The password must contain one digit, one uppercase letter, one lower case letter and one symbol cnCouchbaseSuperUserPassword : Test1234# # -- Couchbase URL. This should be in FQDN format for either remote or local Couchbase clusters. The address can be an internal address inside the kubernetes cluster cnCouchbaseUrl : cbjanssen.default.svc.cluster.local # -- Couchbase restricted user cnCouchbaseUser : janssen PostgreSQL for persistence storage In a production environment, a production grade PostgreSQL server should be used such as Amazon RDS For testing purposes, you can deploy it on the EKS cluster using the following command: helm install my-release --set auth.postgresPassword=Test1234#,auth.database=gluu -n gluu oci://registry-1.docker.io/bitnamicharts/postgresql Add the following yaml snippet to your override.yaml file: global : cnPersistenceType : sql config : configmap : cnSqlDbName : gluu cnSqlDbPort : 5432 cnSqlDbDialect : pgsql cnSqlDbHost : my-release-postgresql.gluu.svc cnSqlDbUser : postgres cnSqlDbTimezone : UTC cnSqldbUserPassword : Test1234# MySQL for persistence storage In a production environment, a production grade MySQL server should be used such as Amazon RDS For testing purposes, you can deploy it on the EKS cluster using the following command: helm install my-release --set auth.rootPassword=Test1234#,auth.database=gluu -n gluu oci://registry-1.docker.io/bitnamicharts/mysql Add the following yaml snippet to your override.yaml file: global : cnPersistenceType : sql config : configmap : cnSqlDbName : gluu cnSqlDbPort : 3306 cnSqlDbDialect : mysql cnSqlDbHost : my-release-mysql.gluu.svc cnSqlDbUser : root cnSqlDbTimezone : UTC cnSqldbUserPassword : Test1234# So if your desired configuration has FQDN and MySQL, the final override.yaml file will look something like that: global : cnPersistenceType : sql isFqdnRegistered : true fqdn : demoexample.gluu.org #CHANGE-THIS to the FQDN used for Gluu nginx-ingress : ingress : path : / hosts : - demoexample.gluu.org #CHANGE-THIS to the FQDN used for Gluu tls : - secretName : tls-certificate hosts : - demoexample.gluu.org #CHANGE-THIS to the FQDN used for Gluu config : configmap : lbAddr : http:// #Add LB address from previous command cnSqlDbName : gluu cnSqlDbPort : 3306 cnSqlDbDialect : mysql cnSqlDbHost : my-release-mysql.gluu.svc cnSqlDbUser : root cnSqlDbTimezone : UTC cnSqldbUserPassword : Test1234# Install Gluu Flex After finishing all the tweaks to the override.yaml file, we can use it to install gluu flex. helm repo add gluu-flex https://docs.gluu.org/charts helm repo update helm install gluu gluu-flex/gluu -n gluu -f override.yaml","title":"Gluu Flex Installation using Helm"},{"location":"install/helm-install/amazon-eks/#configure-gluu-flex","text":"You can use the Janssen TUI to configure Flex components. The TUI calls the Config API to perform ad hoc configuration.","title":"Configure Gluu Flex"},{"location":"install/helm-install/google-gke/","tags":["administration","installation","helm","GKE","Google Cloud","GCP"],"text":"Install Gluu Flex on GKE # System Requirements # The resources may be set minimally to the below: 8-13 GB RAM based on the services deployed 8-11 CPU cores based on the services deployed 50GB hard-disk Use the listing below for a detailed estimation of the minimum required resources. The table contains the default resources recommendation per service. Depending on the use of each service the resources need may be increase or decrease. Service CPU Unit RAM Disk Space Processor Type Required Auth server 2.5 2.5GB N/A 64 Bit Yes fido2 0.5 0.5GB N/A 64 Bit No scim 1 1GB N/A 64 Bit No config - job 0.3 0.3GB N/A 64 Bit Yes on fresh installs persistence - job 0.3 0.3GB N/A 64 Bit Yes on fresh installs nginx 1 1GB N/A 64 Bit Yes if ALB/Istio not used auth-key-rotation 0.3 0.3GB N/A 64 Bit No [Strongly recommended] config-api 1 1GB N/A 64 Bit No casa 0.5 0.5GB N/A 64 Bit No admin-ui 2 2GB N/A 64 Bit No link 0.5 1GB N/A 64 Bit No saml 0.5 1GB N/A 64 Bit No Releases of images are in style 1.0.0-beta.0, 1.0.0-0 Initial Setup # Before initiating the setup, please obtain an SSA for Flex trial, after which you will issued a JWT. Enable GKE API if not enabled yet. If you are using Cloud Shell , you can skip to step 7. Install gcloud . Install kubectl using gcloud components install kubectl command. Install Helm3 . Create cluster using a command such as the following example: gcloud container clusters create gluu-cluster --num-nodes 2 --machine-type e2-standard-4 --zone us-west1-a You can adjust num-nodes and machine-type as per your desired cluster size Create gluu namespace where our resources will reside kubectl create namespace gluu Gluu Flex Installation using Helm # Install Nginx-Ingress , if you are not using Istio ingress helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx helm repo add stable https://charts.helm.sh/stable helm repo update helm install nginx ingress-nginx/ingress-nginx Create a file named override.yaml and add changes as per your desired configuration: FQDN/domain is not registered: Get the Loadbalancer IP: kubectl get svc nginx-ingress-nginx-controller --output jsonpath='{.status.loadBalancer.ingress[0].ip}' Add the following yaml snippet to your override.yaml file: global : lbIp : #Add the Loadbalance IP from the previous command isFqdnRegistered : false FQDN/domain is registered: Add the following yaml snippet to your override.yaml file: global : lbIp : #Add the LoadBalancer IP from the previous command isFqdnRegistered : true fqdn : demoexample.gluu.org #CHANGE-THIS to the FQDN used for Gluu nginx-ingress : ingress : path : / hosts : - demoexample.gluu.org #CHANGE-THIS to the FQDN used for Gluu tls : - secretName : tls-certificate hosts : - demoexample.gluu.org #CHANGE-THIS to the FQDN used for Gluu Couchbase for pesistence storage Add the following yaml snippet to your override.yaml file: global : cnPersistenceType : couchbase config : configmap : # The prefix of couchbase buckets. This helps with separation in between different environments and allows for the same couchbase cluster to be used by different setups of Flex. cnCouchbaseBucketPrefix : jans # -- Couchbase certificate authority string. This must be encoded using base64. This can also be found in your couchbase UI Security > Root Certificate. In mTLS setups this is not required. cnCouchbaseCrt : SWFtTm90YVNlcnZpY2VBY2NvdW50Q2hhbmdlTWV0b09uZQo= # -- The number of replicas per index created. Please note that the number of index nodes must be one greater than the number of index replicas. That means if your couchbase cluster only has 2 index nodes you cannot place the number of replicas to be higher than 1. cnCouchbaseIndexNumReplica : 0 # -- Couchbase password for the restricted user config.configmap.cnCouchbaseUser that is often used inside the services. The password must contain one digit, one uppercase letter, one lower case letter and one symbol cnCouchbasePassword : P@ssw0rd # -- The Couchbase super user (admin) username. This user is used during initialization only. cnCouchbaseSuperUser : admin # -- Couchbase password for the superuser config.configmap.cnCouchbaseSuperUser that is used during the initialization process. The password must contain one digit, one uppercase letter, one lower case letter and one symbol cnCouchbaseSuperUserPassword : Test1234# # -- Couchbase URL. This should be in FQDN format for either remote or local Couchbase clusters. The address can be an internal address inside the kubernetes cluster cnCouchbaseUrl : cbjanssen.default.svc.cluster.local # -- Couchbase restricted user cnCouchbaseUser : janssen PostgreSQL for persistence storage In a production environment, a production grade PostgreSQL server should be used such as Cloud SQL For testing purposes, you can deploy it on the GKE cluster using the following command: helm install my-release --set auth.postgresPassword=Test1234#,auth.database=gluu -n gluu oci://registry-1.docker.io/bitnamicharts/postgresql Add the following yaml snippet to your override.yaml file: global : cnPersistenceType : sql config : configmap : cnSqlDbName : gluu cnSqlDbPort : 5432 cnSqlDbDialect : pgsql cnSqlDbHost : my-release-postgresql.gluu.svc cnSqlDbUser : postgres cnSqlDbTimezone : UTC cnSqldbUserPassword : Test1234# MySQL for persistence storage In a production environment, a production grade MySQL server should be used such as Cloud SQL For testing purposes, you can deploy it on the GKE cluster using the following command: helm install my-release --set auth.rootPassword=Test1234#,auth.database=gluu -n gluu oci://registry-1.docker.io/bitnamicharts/mysql Add the following yaml snippet to your override.yaml file: global : cnPersistenceType : sql config : configmap : cnSqlDbName : gluu cnSqlDbPort : 3306 cnSqlDbDialect : mysql cnSqlDbHost : my-release-mysql.gluu.svc cnSqlDbUser : root cnSqlDbTimezone : UTC cnSqldbUserPassword : Test1234# So if your desired configuration has FQDN and MySQL, the final override.yaml file will look something like that: global : cnPersistenceType : sql lbIp : \"\" #Add the LoadBalancer IP from previous command isFqdnRegistered : true fqdn : demoexample.gluu.org #CHANGE-THIS to the FQDN used for Gluu nginx-ingress : ingress : path : / hosts : - demoexample.gluu.org #CHANGE-THIS to the FQDN used for Gluu tls : - secretName : tls-certificate hosts : - demoexample.gluu.org #CHANGE-THIS to the FQDN used for Gluu config : configmap : cnSqlDbName : gluu cnSqlDbPort : 3306 cnSqlDbDialect : mysql cnSqlDbHost : my-release-mysql.gluu.svc cnSqlDbUser : root cnSqlDbTimezone : UTC cnSqldbUserPassword : Test1234# Install Gluu Flex After finishing all the tweaks to the override.yaml file, we can use it to install gluu flex. helm repo add gluu-flex https://docs.gluu.org/charts helm repo update helm install gluu gluu-flex/gluu -n gluu -f override.yaml Configure Gluu Flex # You can use the Janssen TUI to configure Flex components. The TUI calls the Config API to perform ad hoc configuration.","title":"Google GKE"},{"location":"install/helm-install/google-gke/#install-gluu-flex-on-gke","text":"","title":"Install Gluu Flex on GKE"},{"location":"install/helm-install/google-gke/#system-requirements","text":"The resources may be set minimally to the below: 8-13 GB RAM based on the services deployed 8-11 CPU cores based on the services deployed 50GB hard-disk Use the listing below for a detailed estimation of the minimum required resources. The table contains the default resources recommendation per service. Depending on the use of each service the resources need may be increase or decrease. Service CPU Unit RAM Disk Space Processor Type Required Auth server 2.5 2.5GB N/A 64 Bit Yes fido2 0.5 0.5GB N/A 64 Bit No scim 1 1GB N/A 64 Bit No config - job 0.3 0.3GB N/A 64 Bit Yes on fresh installs persistence - job 0.3 0.3GB N/A 64 Bit Yes on fresh installs nginx 1 1GB N/A 64 Bit Yes if ALB/Istio not used auth-key-rotation 0.3 0.3GB N/A 64 Bit No [Strongly recommended] config-api 1 1GB N/A 64 Bit No casa 0.5 0.5GB N/A 64 Bit No admin-ui 2 2GB N/A 64 Bit No link 0.5 1GB N/A 64 Bit No saml 0.5 1GB N/A 64 Bit No Releases of images are in style 1.0.0-beta.0, 1.0.0-0","title":"System Requirements"},{"location":"install/helm-install/google-gke/#initial-setup","text":"Before initiating the setup, please obtain an SSA for Flex trial, after which you will issued a JWT. Enable GKE API if not enabled yet. If you are using Cloud Shell , you can skip to step 7. Install gcloud . Install kubectl using gcloud components install kubectl command. Install Helm3 . Create cluster using a command such as the following example: gcloud container clusters create gluu-cluster --num-nodes 2 --machine-type e2-standard-4 --zone us-west1-a You can adjust num-nodes and machine-type as per your desired cluster size Create gluu namespace where our resources will reside kubectl create namespace gluu","title":"Initial Setup"},{"location":"install/helm-install/google-gke/#gluu-flex-installation-using-helm","text":"Install Nginx-Ingress , if you are not using Istio ingress helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx helm repo add stable https://charts.helm.sh/stable helm repo update helm install nginx ingress-nginx/ingress-nginx Create a file named override.yaml and add changes as per your desired configuration: FQDN/domain is not registered: Get the Loadbalancer IP: kubectl get svc nginx-ingress-nginx-controller --output jsonpath='{.status.loadBalancer.ingress[0].ip}' Add the following yaml snippet to your override.yaml file: global : lbIp : #Add the Loadbalance IP from the previous command isFqdnRegistered : false FQDN/domain is registered: Add the following yaml snippet to your override.yaml file: global : lbIp : #Add the LoadBalancer IP from the previous command isFqdnRegistered : true fqdn : demoexample.gluu.org #CHANGE-THIS to the FQDN used for Gluu nginx-ingress : ingress : path : / hosts : - demoexample.gluu.org #CHANGE-THIS to the FQDN used for Gluu tls : - secretName : tls-certificate hosts : - demoexample.gluu.org #CHANGE-THIS to the FQDN used for Gluu Couchbase for pesistence storage Add the following yaml snippet to your override.yaml file: global : cnPersistenceType : couchbase config : configmap : # The prefix of couchbase buckets. This helps with separation in between different environments and allows for the same couchbase cluster to be used by different setups of Flex. cnCouchbaseBucketPrefix : jans # -- Couchbase certificate authority string. This must be encoded using base64. This can also be found in your couchbase UI Security > Root Certificate. In mTLS setups this is not required. cnCouchbaseCrt : SWFtTm90YVNlcnZpY2VBY2NvdW50Q2hhbmdlTWV0b09uZQo= # -- The number of replicas per index created. Please note that the number of index nodes must be one greater than the number of index replicas. That means if your couchbase cluster only has 2 index nodes you cannot place the number of replicas to be higher than 1. cnCouchbaseIndexNumReplica : 0 # -- Couchbase password for the restricted user config.configmap.cnCouchbaseUser that is often used inside the services. The password must contain one digit, one uppercase letter, one lower case letter and one symbol cnCouchbasePassword : P@ssw0rd # -- The Couchbase super user (admin) username. This user is used during initialization only. cnCouchbaseSuperUser : admin # -- Couchbase password for the superuser config.configmap.cnCouchbaseSuperUser that is used during the initialization process. The password must contain one digit, one uppercase letter, one lower case letter and one symbol cnCouchbaseSuperUserPassword : Test1234# # -- Couchbase URL. This should be in FQDN format for either remote or local Couchbase clusters. The address can be an internal address inside the kubernetes cluster cnCouchbaseUrl : cbjanssen.default.svc.cluster.local # -- Couchbase restricted user cnCouchbaseUser : janssen PostgreSQL for persistence storage In a production environment, a production grade PostgreSQL server should be used such as Cloud SQL For testing purposes, you can deploy it on the GKE cluster using the following command: helm install my-release --set auth.postgresPassword=Test1234#,auth.database=gluu -n gluu oci://registry-1.docker.io/bitnamicharts/postgresql Add the following yaml snippet to your override.yaml file: global : cnPersistenceType : sql config : configmap : cnSqlDbName : gluu cnSqlDbPort : 5432 cnSqlDbDialect : pgsql cnSqlDbHost : my-release-postgresql.gluu.svc cnSqlDbUser : postgres cnSqlDbTimezone : UTC cnSqldbUserPassword : Test1234# MySQL for persistence storage In a production environment, a production grade MySQL server should be used such as Cloud SQL For testing purposes, you can deploy it on the GKE cluster using the following command: helm install my-release --set auth.rootPassword=Test1234#,auth.database=gluu -n gluu oci://registry-1.docker.io/bitnamicharts/mysql Add the following yaml snippet to your override.yaml file: global : cnPersistenceType : sql config : configmap : cnSqlDbName : gluu cnSqlDbPort : 3306 cnSqlDbDialect : mysql cnSqlDbHost : my-release-mysql.gluu.svc cnSqlDbUser : root cnSqlDbTimezone : UTC cnSqldbUserPassword : Test1234# So if your desired configuration has FQDN and MySQL, the final override.yaml file will look something like that: global : cnPersistenceType : sql lbIp : \"\" #Add the LoadBalancer IP from previous command isFqdnRegistered : true fqdn : demoexample.gluu.org #CHANGE-THIS to the FQDN used for Gluu nginx-ingress : ingress : path : / hosts : - demoexample.gluu.org #CHANGE-THIS to the FQDN used for Gluu tls : - secretName : tls-certificate hosts : - demoexample.gluu.org #CHANGE-THIS to the FQDN used for Gluu config : configmap : cnSqlDbName : gluu cnSqlDbPort : 3306 cnSqlDbDialect : mysql cnSqlDbHost : my-release-mysql.gluu.svc cnSqlDbUser : root cnSqlDbTimezone : UTC cnSqldbUserPassword : Test1234# Install Gluu Flex After finishing all the tweaks to the override.yaml file, we can use it to install gluu flex. helm repo add gluu-flex https://docs.gluu.org/charts helm repo update helm install gluu gluu-flex/gluu -n gluu -f override.yaml","title":"Gluu Flex Installation using Helm"},{"location":"install/helm-install/google-gke/#configure-gluu-flex","text":"You can use the Janssen TUI to configure Flex components. The TUI calls the Config API to perform ad hoc configuration.","title":"Configure Gluu Flex"},{"location":"install/helm-install/local/","tags":["administration","installation","helm"],"text":"Install Gluu Server Locally with minikube and MicroK8s # System Requirements # For local deployments like minikube and MicroK8s or cloud installations in demo mode, resources may be set to the minimum as below: 8 GB RAM 4 CPU cores 50 GB hard-disk Use the listing below for detailed estimation of minimum required resources. Table contains the default resources recommendations per service. Depending on the use of each service the resources needs may increase or decrease. Service CPU Unit RAM Disk Space Processor Type Required Auth server 2.5 2.5GB N/A 64 Bit Yes fido2 0.5 0.5GB N/A 64 Bit No scim 1 1GB N/A 64 Bit No config - job 0.3 0.3GB N/A 64 Bit Yes on fresh installs persistence - job 0.3 0.3GB N/A 64 Bit Yes on fresh installs nginx 1 1GB N/A 64 Bit Yes ALB/Istio not used auth-key-rotation 0.3 0.3GB N/A 64 Bit No [Strongly recommended] config-api 1 1GB N/A 64 Bit No casa 0.5 0.5GB N/A 64 Bit No admin-ui 2 2GB N/A 64 Bit No link 0.5 1GB N/A 64 Bit No saml 0.5 1GB N/A 64 Bit No Releases of images are in style 1.0.0-beta.0, 1.0.0-0 Installation Steps # Before initiating the setup, please obtain an SSA for Flex trial, after which you will issued a JWT. Start a fresh Ubuntu 18.04 / 20.04 / 22.04 VM with ports 443 and 80 open. Then execute the following: sudo su - wget https://raw.githubusercontent.com/GluuFederation/flex/vreplace-flex-version/automation/startflexdemo.sh && chmod u+x startflexdemo.sh && ./startflexdemo.sh This will install Docker, Microk8s, Helm and Gluu with the default settings that can be found inside values.yaml . The installer will automatically add a record to your hosts record in the VM but if you want to access the endpoints outside the VM you must map the ip of the instance running Ubuntu to the FQDN you provided and then access the endpoints at your browser such in the example in the table below. Service Example endpoint Auth server https://FQDN/.well-known/openid-configuration fido2 https://FQDN/.well-known/fido2-configuration scim https://FQDN/.well-known/scim-configuration Casa https://FQDN/jans-casa Admin-UI https://FQDN/admin Configure Gluu Flex # You can use the Janssen TUI to configure Flex components. The TUI calls the Config API to perform ad hoc configuration.","title":"Local Kubernetes Cluster"},{"location":"install/helm-install/local/#install-gluu-server-locally-with-minikube-and-microk8s","text":"","title":"Install Gluu Server Locally with minikube and MicroK8s"},{"location":"install/helm-install/local/#system-requirements","text":"For local deployments like minikube and MicroK8s or cloud installations in demo mode, resources may be set to the minimum as below: 8 GB RAM 4 CPU cores 50 GB hard-disk Use the listing below for detailed estimation of minimum required resources. Table contains the default resources recommendations per service. Depending on the use of each service the resources needs may increase or decrease. Service CPU Unit RAM Disk Space Processor Type Required Auth server 2.5 2.5GB N/A 64 Bit Yes fido2 0.5 0.5GB N/A 64 Bit No scim 1 1GB N/A 64 Bit No config - job 0.3 0.3GB N/A 64 Bit Yes on fresh installs persistence - job 0.3 0.3GB N/A 64 Bit Yes on fresh installs nginx 1 1GB N/A 64 Bit Yes ALB/Istio not used auth-key-rotation 0.3 0.3GB N/A 64 Bit No [Strongly recommended] config-api 1 1GB N/A 64 Bit No casa 0.5 0.5GB N/A 64 Bit No admin-ui 2 2GB N/A 64 Bit No link 0.5 1GB N/A 64 Bit No saml 0.5 1GB N/A 64 Bit No Releases of images are in style 1.0.0-beta.0, 1.0.0-0","title":"System Requirements"},{"location":"install/helm-install/local/#installation-steps","text":"Before initiating the setup, please obtain an SSA for Flex trial, after which you will issued a JWT. Start a fresh Ubuntu 18.04 / 20.04 / 22.04 VM with ports 443 and 80 open. Then execute the following: sudo su - wget https://raw.githubusercontent.com/GluuFederation/flex/vreplace-flex-version/automation/startflexdemo.sh && chmod u+x startflexdemo.sh && ./startflexdemo.sh This will install Docker, Microk8s, Helm and Gluu with the default settings that can be found inside values.yaml . The installer will automatically add a record to your hosts record in the VM but if you want to access the endpoints outside the VM you must map the ip of the instance running Ubuntu to the FQDN you provided and then access the endpoints at your browser such in the example in the table below. Service Example endpoint Auth server https://FQDN/.well-known/openid-configuration fido2 https://FQDN/.well-known/fido2-configuration scim https://FQDN/.well-known/scim-configuration Casa https://FQDN/jans-casa Admin-UI https://FQDN/admin","title":"Installation Steps"},{"location":"install/helm-install/local/#configure-gluu-flex","text":"You can use the Janssen TUI to configure Flex components. The TUI calls the Config API to perform ad hoc configuration.","title":"Configure Gluu Flex"},{"location":"install/helm-install/microsoft-azure/","tags":["administration","installation","helm","AKS","Microsoft","Azure"],"text":"Install Gluu Flex on AKS # System Requirements # The resources may be set minimally to the below: 8-13 GB RAM based on the services deployed 8-11 CPU cores based on the services deployed 50GB hard-disk Use the listing below for a detailed estimation of the minimum required resources. The table contains the default resources recommendation per service. Depending on the use of each service the resources need may be increase or decrease. Service CPU Unit RAM Disk Space Processor Type Required Auth server 2.5 2.5GB N/A 64 Bit Yes fido2 0.5 0.5GB N/A 64 Bit No scim 1 1GB N/A 64 Bit No config - job 0.3 0.3GB N/A 64 Bit Yes on fresh installs persistence - job 0.3 0.3GB N/A 64 Bit Yes on fresh installs nginx 1 1GB N/A 64 Bit Yes if ALB/Istio not used auth-key-rotation 0.3 0.3GB N/A 64 Bit No [Strongly recommended] config-api 1 1GB N/A 64 Bit No casa 0.5 0.5GB N/A 64 Bit No admin-ui 2 2GB N/A 64 Bit No link 0.5 1GB N/A 64 Bit No saml 0.5 1GB N/A 64 Bit No Releases of images are in style 1.0.0-beta.0, 1.0.0-0 Initial Setup # Before initiating the setup, please obtain an SSA for Flex trial, after which you will issued a JWT. Install Azure CLI Create a Resource Group az group create --name gluu-resource-group --location eastus Create an AKS cluster such as the following example: az aks create -g gluu-resource-group -n gluu-cluster --enable-managed-identity --node-vm-size NODE_TYPE --node-count 2 --enable-addons monitoring --enable-msi-auth-for-monitoring --generate-ssh-keys You can adjust node-count and node-vm-size as per your desired cluster size Connect to the cluster az aks install-cli az aks get-credentials --resource-group gluu-resource-group --name gluu-cluster Install Helm3 Create gluu namespace where our resources will reside kubectl create namespace gluu Gluu Flex Installation using Helm # Install Nginx-Ingress , if you are not using Istio ingress helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx helm repo add stable https://charts.helm.sh/stable helm repo update helm install nginx ingress-nginx/ingress-nginx Create a file named override.yaml and add changes as per your desired configuration: FQDN/domain is not registered: Get the Loadbalancer IP: kubectl get svc nginx-ingress-nginx-controller --output jsonpath='{.status.loadBalancer.ingress[0].ip}' Add the following yaml snippet to your override.yaml file: global : lbIp : #Add the Loadbalance IP from the previous command isFqdnRegistered : false FQDN/domain is registered: Add the following yaml snippet to your override.yaml file: global : lbIp : #Add the LoadBalancer IP from the previous command isFqdnRegistered : true fqdn : demoexample.gluu.org #CHANGE-THIS to the FQDN used for Gluu nginx-ingress : ingress : path : / hosts : - demoexample.gluu.org #CHANGE-THIS to the FQDN used for Gluu tls : - secretName : tls-certificate hosts : - demoexample.gluu.org #CHANGE-THIS to the FQDN used for Gluu Couchbase for pesistence storage Add the following yaml snippet to your override.yaml file: global : cnPersistenceType : couchbase config : configmap : # The prefix of couchbase buckets. This helps with separation in between different environments and allows for the same couchbase cluster to be used by different setups of Janssen. cnCouchbaseBucketPrefix : jans # -- Couchbase certificate authority string. This must be encoded using base64. This can also be found in your couchbase UI Security > Root Certificate. In mTLS setups this is not required. cnCouchbaseCrt : SWFtTm90YVNlcnZpY2VBY2NvdW50Q2hhbmdlTWV0b09uZQo= # -- The number of replicas per index created. Please note that the number of index nodes must be one greater than the number of index replicas. That means if your couchbase cluster only has 2 index nodes you cannot place the number of replicas to be higher than 1. cnCouchbaseIndexNumReplica : 0 # -- Couchbase password for the restricted user config.configmap.cnCouchbaseUser that is often used inside the services. The password must contain one digit, one uppercase letter, one lower case letter and one symbol cnCouchbasePassword : P@ssw0rd # -- The Couchbase super user (admin) username. This user is used during initialization only. cnCouchbaseSuperUser : admin # -- Couchbase password for the superuser config.configmap.cnCouchbaseSuperUser that is used during the initialization process. The password must contain one digit, one uppercase letter, one lower case letter and one symbol cnCouchbaseSuperUserPassword : Test1234# # -- Couchbase URL. This should be in FQDN format for either remote or local Couchbase clusters. The address can be an internal address inside the kubernetes cluster cnCouchbaseUrl : cbjanssen.default.svc.cluster.local # -- Couchbase restricted user cnCouchbaseUser : janssen PostgreSQL for persistence storage In a production environment, a production grade PostgreSQL server should be used such as Azure Database for PostgreSQL For testing purposes, you can deploy it on the AKS cluster using the following command: helm install my-release --set auth.postgresPassword=Test1234#,auth.database=gluu -n gluu oci://registry-1.docker.io/bitnamicharts/postgresql Add the following yaml snippet to your override.yaml file: global : cnPersistenceType : sql config : configmap : cnSqlDbName : gluu cnSqlDbPort : 5432 cnSqlDbDialect : pgsql cnSqlDbHost : my-release-postgresql.gluu.svc cnSqlDbUser : postgres cnSqlDbTimezone : UTC cnSqldbUserPassword : Test1234# MySQL for persistence storage In a production environment, a production grade MySQL server should be used such as Azure Database for MySQL For testing purposes, you can deploy it on the AKS cluster using the following command: helm install my-release --set auth.rootPassword=Test1234#,auth.database=gluu -n gluu oci://registry-1.docker.io/bitnamicharts/mysql Add the following yaml snippet to your override.yaml file: global : cnPersistenceType : sql config : configmap : cnSqlDbName : gluu cnSqlDbPort : 3306 cnSqlDbDialect : mysql cnSqlDbHost : my-release-mysql.gluu.svc cnSqlDbUser : root cnSqlDbTimezone : UTC cnSqldbUserPassword : Test1234# So if your desired configuration has FQDN and MySQL, the final override.yaml file will look something like that: global : cnPersistenceType : sql lbIp : \"\" #Add the LoadBalancer IP from previous command isFqdnRegistered : true fqdn : demoexample.gluu.org #CHANGE-THIS to the FQDN used for Gluu nginx-ingress : ingress : path : / hosts : - demoexample.gluu.org #CHANGE-THIS to the FQDN used for Gluu tls : - secretName : tls-certificate hosts : - demoexample.gluu.org #CHANGE-THIS to the FQDN used for Gluu config : configmap : cnSqlDbName : gluu cnSqlDbPort : 3306 cnSqlDbDialect : mysql cnSqlDbHost : my-release-mysql.gluu.svc cnSqlDbUser : root cnSqlDbTimezone : UTC cnSqldbUserPassword : Test1234# Install Gluu Flex After finishing all the tweaks to the override.yaml file, we can use it to install gluu flex. helm repo add gluu-flex https://docs.gluu.org/charts helm repo update helm install gluu gluu-flex/gluu -n gluu -f override.yaml Configure Gluu Flex # You can use the Janssen TUI to configure Flex components. The TUI calls the Config API to perform ad hoc configuration.","title":"Microsoft Azure AKS"},{"location":"install/helm-install/microsoft-azure/#install-gluu-flex-on-aks","text":"","title":"Install Gluu Flex on AKS"},{"location":"install/helm-install/microsoft-azure/#system-requirements","text":"The resources may be set minimally to the below: 8-13 GB RAM based on the services deployed 8-11 CPU cores based on the services deployed 50GB hard-disk Use the listing below for a detailed estimation of the minimum required resources. The table contains the default resources recommendation per service. Depending on the use of each service the resources need may be increase or decrease. Service CPU Unit RAM Disk Space Processor Type Required Auth server 2.5 2.5GB N/A 64 Bit Yes fido2 0.5 0.5GB N/A 64 Bit No scim 1 1GB N/A 64 Bit No config - job 0.3 0.3GB N/A 64 Bit Yes on fresh installs persistence - job 0.3 0.3GB N/A 64 Bit Yes on fresh installs nginx 1 1GB N/A 64 Bit Yes if ALB/Istio not used auth-key-rotation 0.3 0.3GB N/A 64 Bit No [Strongly recommended] config-api 1 1GB N/A 64 Bit No casa 0.5 0.5GB N/A 64 Bit No admin-ui 2 2GB N/A 64 Bit No link 0.5 1GB N/A 64 Bit No saml 0.5 1GB N/A 64 Bit No Releases of images are in style 1.0.0-beta.0, 1.0.0-0","title":"System Requirements"},{"location":"install/helm-install/microsoft-azure/#initial-setup","text":"Before initiating the setup, please obtain an SSA for Flex trial, after which you will issued a JWT. Install Azure CLI Create a Resource Group az group create --name gluu-resource-group --location eastus Create an AKS cluster such as the following example: az aks create -g gluu-resource-group -n gluu-cluster --enable-managed-identity --node-vm-size NODE_TYPE --node-count 2 --enable-addons monitoring --enable-msi-auth-for-monitoring --generate-ssh-keys You can adjust node-count and node-vm-size as per your desired cluster size Connect to the cluster az aks install-cli az aks get-credentials --resource-group gluu-resource-group --name gluu-cluster Install Helm3 Create gluu namespace where our resources will reside kubectl create namespace gluu","title":"Initial Setup"},{"location":"install/helm-install/microsoft-azure/#gluu-flex-installation-using-helm","text":"Install Nginx-Ingress , if you are not using Istio ingress helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx helm repo add stable https://charts.helm.sh/stable helm repo update helm install nginx ingress-nginx/ingress-nginx Create a file named override.yaml and add changes as per your desired configuration: FQDN/domain is not registered: Get the Loadbalancer IP: kubectl get svc nginx-ingress-nginx-controller --output jsonpath='{.status.loadBalancer.ingress[0].ip}' Add the following yaml snippet to your override.yaml file: global : lbIp : #Add the Loadbalance IP from the previous command isFqdnRegistered : false FQDN/domain is registered: Add the following yaml snippet to your override.yaml file: global : lbIp : #Add the LoadBalancer IP from the previous command isFqdnRegistered : true fqdn : demoexample.gluu.org #CHANGE-THIS to the FQDN used for Gluu nginx-ingress : ingress : path : / hosts : - demoexample.gluu.org #CHANGE-THIS to the FQDN used for Gluu tls : - secretName : tls-certificate hosts : - demoexample.gluu.org #CHANGE-THIS to the FQDN used for Gluu Couchbase for pesistence storage Add the following yaml snippet to your override.yaml file: global : cnPersistenceType : couchbase config : configmap : # The prefix of couchbase buckets. This helps with separation in between different environments and allows for the same couchbase cluster to be used by different setups of Janssen. cnCouchbaseBucketPrefix : jans # -- Couchbase certificate authority string. This must be encoded using base64. This can also be found in your couchbase UI Security > Root Certificate. In mTLS setups this is not required. cnCouchbaseCrt : SWFtTm90YVNlcnZpY2VBY2NvdW50Q2hhbmdlTWV0b09uZQo= # -- The number of replicas per index created. Please note that the number of index nodes must be one greater than the number of index replicas. That means if your couchbase cluster only has 2 index nodes you cannot place the number of replicas to be higher than 1. cnCouchbaseIndexNumReplica : 0 # -- Couchbase password for the restricted user config.configmap.cnCouchbaseUser that is often used inside the services. The password must contain one digit, one uppercase letter, one lower case letter and one symbol cnCouchbasePassword : P@ssw0rd # -- The Couchbase super user (admin) username. This user is used during initialization only. cnCouchbaseSuperUser : admin # -- Couchbase password for the superuser config.configmap.cnCouchbaseSuperUser that is used during the initialization process. The password must contain one digit, one uppercase letter, one lower case letter and one symbol cnCouchbaseSuperUserPassword : Test1234# # -- Couchbase URL. This should be in FQDN format for either remote or local Couchbase clusters. The address can be an internal address inside the kubernetes cluster cnCouchbaseUrl : cbjanssen.default.svc.cluster.local # -- Couchbase restricted user cnCouchbaseUser : janssen PostgreSQL for persistence storage In a production environment, a production grade PostgreSQL server should be used such as Azure Database for PostgreSQL For testing purposes, you can deploy it on the AKS cluster using the following command: helm install my-release --set auth.postgresPassword=Test1234#,auth.database=gluu -n gluu oci://registry-1.docker.io/bitnamicharts/postgresql Add the following yaml snippet to your override.yaml file: global : cnPersistenceType : sql config : configmap : cnSqlDbName : gluu cnSqlDbPort : 5432 cnSqlDbDialect : pgsql cnSqlDbHost : my-release-postgresql.gluu.svc cnSqlDbUser : postgres cnSqlDbTimezone : UTC cnSqldbUserPassword : Test1234# MySQL for persistence storage In a production environment, a production grade MySQL server should be used such as Azure Database for MySQL For testing purposes, you can deploy it on the AKS cluster using the following command: helm install my-release --set auth.rootPassword=Test1234#,auth.database=gluu -n gluu oci://registry-1.docker.io/bitnamicharts/mysql Add the following yaml snippet to your override.yaml file: global : cnPersistenceType : sql config : configmap : cnSqlDbName : gluu cnSqlDbPort : 3306 cnSqlDbDialect : mysql cnSqlDbHost : my-release-mysql.gluu.svc cnSqlDbUser : root cnSqlDbTimezone : UTC cnSqldbUserPassword : Test1234# So if your desired configuration has FQDN and MySQL, the final override.yaml file will look something like that: global : cnPersistenceType : sql lbIp : \"\" #Add the LoadBalancer IP from previous command isFqdnRegistered : true fqdn : demoexample.gluu.org #CHANGE-THIS to the FQDN used for Gluu nginx-ingress : ingress : path : / hosts : - demoexample.gluu.org #CHANGE-THIS to the FQDN used for Gluu tls : - secretName : tls-certificate hosts : - demoexample.gluu.org #CHANGE-THIS to the FQDN used for Gluu config : configmap : cnSqlDbName : gluu cnSqlDbPort : 3306 cnSqlDbDialect : mysql cnSqlDbHost : my-release-mysql.gluu.svc cnSqlDbUser : root cnSqlDbTimezone : UTC cnSqldbUserPassword : Test1234# Install Gluu Flex After finishing all the tweaks to the override.yaml file, we can use it to install gluu flex. helm repo add gluu-flex https://docs.gluu.org/charts helm repo update helm install gluu gluu-flex/gluu -n gluu -f override.yaml","title":"Gluu Flex Installation using Helm"},{"location":"install/helm-install/microsoft-azure/#configure-gluu-flex","text":"You can use the Janssen TUI to configure Flex components. The TUI calls the Config API to perform ad hoc configuration.","title":"Configure Gluu Flex"},{"location":"install/helm-install/rancher/","tags":["administration","installation","helm"],"text":"Install Gluu Server Using Rancher Marketplace # For a more generic Gluu Flex installation on Rancher, you can follow this comprehensive guide. Also, there are multiple Rancher installation options . For this quick start setup we will use a single node Kubernetes install in docker with a self-signed certificate . Installation Steps # Note If you are deploying an Ingress controller on a single node deployment, in which Ingress utilizes ports 80 and 443, then you have to adjust the host ports mapped for the rancher/rancher container. Here's an example on how to do that. Before initiating the setup, please obtain an SSA for Flex trial, after which you will issued a JWT. Provision a Linux 4 CPU, 16 GB RAM, and 50GB SSD VM with ports 443 and 80 open. Save the VM IP address. For development environments, the VM can be set up using VMWare Workstation Player or VirtualBox with Ubuntu 20.04 operating system running on a VM. Install Docker . Execute docker run -d --restart = unless-stopped -p 80 :80 -p 443 :443 --privileged rancher/rancher:latest The final line of the returned text is the container-id , which you'll need for the next step. Execute the following command to get the bootstrap password for login. docker logs 2 > & 1 | grep \"Bootstrap Password:\" Head to https:// and log in with the username admin and the password from the previous step. If you are logging into Rancher for the first time, you'll need to enter just the password, and on the next step, Rancher will ask you to reset your current password. Next, you'll see the Rancher home page with a list of existing clusters. By default, the name of the newly created cluster would be local . Click on the cluster name to go to the dashboard. From the top-left menu expand Apps and click Charts . Search for Gluu and begin your installation. During Step 1 of installation, be sure to select the Customize Helm options before install option. In Step 2, customize the settings for the Gluu installation. Specifically Optional Services from where you can enable Gluu modules. In Step 3, unselect the Wait option and start the installation.","title":"Rancher Marketplace"},{"location":"install/helm-install/rancher/#install-gluu-server-using-rancher-marketplace","text":"For a more generic Gluu Flex installation on Rancher, you can follow this comprehensive guide. Also, there are multiple Rancher installation options . For this quick start setup we will use a single node Kubernetes install in docker with a self-signed certificate .","title":"Install Gluu Server Using Rancher Marketplace"},{"location":"install/helm-install/rancher/#installation-steps","text":"Note If you are deploying an Ingress controller on a single node deployment, in which Ingress utilizes ports 80 and 443, then you have to adjust the host ports mapped for the rancher/rancher container. Here's an example on how to do that. Before initiating the setup, please obtain an SSA for Flex trial, after which you will issued a JWT. Provision a Linux 4 CPU, 16 GB RAM, and 50GB SSD VM with ports 443 and 80 open. Save the VM IP address. For development environments, the VM can be set up using VMWare Workstation Player or VirtualBox with Ubuntu 20.04 operating system running on a VM. Install Docker . Execute docker run -d --restart = unless-stopped -p 80 :80 -p 443 :443 --privileged rancher/rancher:latest The final line of the returned text is the container-id , which you'll need for the next step. Execute the following command to get the bootstrap password for login. docker logs 2 > & 1 | grep \"Bootstrap Password:\" Head to https:// and log in with the username admin and the password from the previous step. If you are logging into Rancher for the first time, you'll need to enter just the password, and on the next step, Rancher will ask you to reset your current password. Next, you'll see the Rancher home page with a list of existing clusters. By default, the name of the newly created cluster would be local . Click on the cluster name to go to the dashboard. From the top-left menu expand Apps and click Charts . Search for Gluu and begin your installation. During Step 1 of installation, be sure to select the Customize Helm options before install option. In Step 2, customize the settings for the Gluu installation. Specifically Optional Services from where you can enable Gluu modules. In Step 3, unselect the Wait option and start the installation.","title":"Installation Steps"},{"location":"install/vm-install/rhel/","tags":["administration","installation","vm","RHEL","CentOS"],"text":"Install Gluu Flex On Red Hat EL # This is a step-by-step guide for installation and uninstallation of Gluu Flex on Ubuntu Linux. Prerequisites # Ensure that the OS platform is one of the supported versions VM should meet VM system requirements Make sure that if SELinux is installed then it is put into permissive mode If the server firewall is running, make sure you allow https , which is needed for OpenID and FIDO. sudo firewall-cmd --permanent --zone = public --add-service = https sudo firewall-cmd --reload ; Install EPEL and mod-auth-openidc as dependencies sudo yum -y install https://dl.fedoraproject.org/pub/epel/epel-release-latest- $( rpm -E %rhel ) .noarch.rpm sudo yum -y module enable mod_auth_openidc ; Please obtain an SSA to trial Flex, after which you are issued a JWT that you can use during installation. SSA should be stored in a text file on an accessible path. Install the Package # Download and Verify the Release Package # Download the release package from the Github Flex Releases wget https://github.com/GluuFederation/flex/releases/download/vreplace-flex-version/flex-replace-flex-version-el8.x86_64.rpm -P /tmp GPG key is used to ensure the authenticity of the downloaded package during the installation process. If the key is not found, the installation step would fail. Use the commands below to download and import the GPG key. wget https://github.com/GluuFederation/flex/files/11814579/automation-flex-public-gpg.zip unzip automation-flex-public-gpg.zip sudo rpm -import automation-flex-public-gpg.asc Verify the integrity of the downloaded package using published sha256sum . Download the sha256sum file for the package wget https://github.com/GluuFederation/flex/releases/download/vreplace-flex-version/flex-replace-flex-version-el8.x86_64.rpm.sha256sum -P /tmp Run the command below from the directory where the downloaded package and the .sha256sum files are located. cd /tmp ; sha256sum -c flex-replace-flex-version-el8.x86_64.rpm.sha256sum ; Output similar to below should confirm the integrity of the downloaded package. flex-replace-flex-version-el8.x86_64.rpm : ok Install the Release Package # sudo yum install ./flex-replace-flex-version-el8.x86_64.rpm Run the setup script # Execute the setup script with command below: sudo python3 /opt/jans/jans-setup/flex/flex-linux-setup/flex_setup.py If Admin-UI component is being installed, then the script will require SSA input, either as text or as a file path. This should be the SSA or file which was acquired as part of prerequisite step . Install Admin UI [Y/n]: y Please enter path of file containing SSA or paste SSA (q to exit): Alternatively, for SSA file can be passed as a parameter to the setup script as below. python3 /opt/jans/jans-setup/flex/flex-linux-setup/flex_setup.py -admin-ui-ssa [ filename ] Verify and Access the Installation # Verify that installation has been successful and all installed components are accessible using the steps below Log in to Text User Interface (TUI) /opt/jans/jans-cli/jans_cli_tui.py Full TUI documentation can be found here Log into Admin-UI using URI below https://FQDN/admin When troubleshooting issues with Admin UI access, it's advisable to check the logs , refer to the FAQ , and review service dependencies for potential solutions. Access Casa using URI below https://FQDN/jans-casa Enabling HTTPS # To enable communication with Janssen Server over TLS (https) in a production environment, Janssen Server needs details about CA certificate. Update the HTTPS cofiguration file https_jans.conf as shown below: Note Want to use Let's Encrypt to get a certificate? Follow this guide . Open https_jans.conf sudo vi /etc/httpd/conf.d/https_jans.conf Update SSLCertificateFile and SSLCertificateKeyFile parameters values SSLCertificateFile location_of_fullchain.pem SSLCertificateKeyFile location_of_privkey.pem Restart httpd service for changes to take effect sudo service httpd restart Uninstallation # Removing Flex is a two step process: Uninstall Gluu Flex Uninstall Janssen Packages If you have not run the setup script, you can skip step 1 and just remove the package. Uninstall Gluu Flex # Use the command below to uninstall the Gluu Flex server sudo python3 /opt/jans/jans-setup/flex/flex-linux-setup/flex_setup.py --remove-flex Output: [ec2-user@manojs1978-lenient-drum ~]$ sudo python3 /opt/jans/jans-setup/flex/flex-linux-setup/flex_setup.py --remove-flex This process is irreversible. Gluu Flex Components will be removed Are you sure to uninstall Gluu Flex? [yes/N] yes Profile was detected as jans. Log Files: /opt/jans/jans-setup/logs/flex-setup.log /opt/jans/jans-setup/logs/flex-setup-error.log /opt/jans/jans-setup/setup_app/pylib/jwt/utils.py:7: CryptographyDeprecationWarning: Python 3.6 is no longer supported by the Python core team. Therefore, support for it is deprecated in cryptography and will be removed in a future release. from cryptography.hazmat.primitives.asymmetric.ec import EllipticCurve Please wait while collecting properties... Uninstalling Gluu Casa - Deleting /etc/default/casa - Deleting /etc/systemd/system/casa.service - Removing casa directives from apache configuration - Deleting /opt/jans/jetty/jans-auth/custom/libs/casa-config.jar - Removing plugin /opt/jans/jetty/jans-auth/custom/libs/casa-config.jar from Jans Auth Configuration - Deleting /opt/jans/python/libs/Casa.py - Deleting /opt/jans/python/libs/casa-external_fido2.py - Deleting /opt/jans/python/libs/casa-external_otp.py - Deleting /opt/jans/python/libs/casa-external_super_gluu.py - Deleting /opt/jans/python/libs/casa-external_twilio_sms.py - Deleting casa client from db backend - Deleting casa client scopes from db backend - Deleting casa configuration from db backend - Deleting script 3000-F75A from db backend - Deleting /opt/jans/jetty/casa Uninstalling Gluu Admin-UI - Deleting Gluu Flex Admin UI Client 2001.931e814d-01e2-4983-898f-91bf93670f7b - Removing Admin UI directives from apache configuration - Deleting /opt/jans/jetty/jans-config-api/custom/libs/gluu-flex-admin-ui-plugin.jar - Removing plugin /opt/jans/jetty/jans-config-api/custom/libs/gluu-flex-admin-ui-plugin.jar from Jans Config API Configuration - Deleting /opt/jans/jetty/jans-config-api/custom/config/log4j2-adminui.xml - Deleting /opt/jans/jetty/jans-config-api/custom/config/log4j2.xml - Rewriting Jans CLI init file for plugins - Deleting /var/www/html/admin Disabling script A51E-76DA Restarting Apache Restarting Jans Auth Restarting Janssen Config Api Uninstall Janssen Packages # The command below removes and uninstall the jans package sudo python3 /opt/jans/jans-setup/install.py -uninstall Output: [ec2-user@manojs1978-lenient-drum ~]$ sudo python3 /opt/jans/jans-setup/install.py -uninstall This process is irreversible. You will lose all data related to Janssen Server. Are you sure to uninstall Janssen Server? [yes/N] yes Uninstalling Jannsen Server... Removing /etc/default/jans-config-api Stopping jans-config-api Removing /etc/default/jans-auth Stopping jans-auth Removing /etc/default/jans-fido2 Stopping jans-fido2 Removing /etc/default/jans-scim Stopping jans-scim Removing /etc/default/jans-cache-refresh Stopping jans-cache-refresh Executing rm -r -f /etc/certs Executing rm -r -f /etc/jans Executing rm -r -f /opt/jans Executing rm -r -f /opt/amazon-corretto* Executing rm -r -f /opt/jre Executing rm -r -f /opt/node* Executing rm -r -f /opt/jetty* Executing rm -r -f /opt/jython* Executing rm -r -f /opt/dist Removing /etc/httpd/conf.d/https_jans.conf Remove Gluu Flex Packages: # List existing Gluu packages with: sudo yum list installed | grep flex Remove packages: sudo yum remove Uninstalling Admin UI # To uninstall the Admin UI from your Flex installation, execute this command: sudo python3 /opt/jans/jans-setup/flex/flex-linux-setup/flex_setup.py --remove-flex Updating Admin UI # To update the Admin UI in an existing Flex installation, execute this command: sudo python3 /opt/jans/jans-setup/flex/flex-linux-setup/flex_setup.py --update-admin-ui","title":"RHEL"},{"location":"install/vm-install/rhel/#install-gluu-flex-on-red-hat-el","text":"This is a step-by-step guide for installation and uninstallation of Gluu Flex on Ubuntu Linux.","title":"Install Gluu Flex On Red Hat EL"},{"location":"install/vm-install/rhel/#prerequisites","text":"Ensure that the OS platform is one of the supported versions VM should meet VM system requirements Make sure that if SELinux is installed then it is put into permissive mode If the server firewall is running, make sure you allow https , which is needed for OpenID and FIDO. sudo firewall-cmd --permanent --zone = public --add-service = https sudo firewall-cmd --reload ; Install EPEL and mod-auth-openidc as dependencies sudo yum -y install https://dl.fedoraproject.org/pub/epel/epel-release-latest- $( rpm -E %rhel ) .noarch.rpm sudo yum -y module enable mod_auth_openidc ; Please obtain an SSA to trial Flex, after which you are issued a JWT that you can use during installation. SSA should be stored in a text file on an accessible path.","title":"Prerequisites"},{"location":"install/vm-install/rhel/#install-the-package","text":"","title":"Install the Package"},{"location":"install/vm-install/rhel/#download-and-verify-the-release-package","text":"Download the release package from the Github Flex Releases wget https://github.com/GluuFederation/flex/releases/download/vreplace-flex-version/flex-replace-flex-version-el8.x86_64.rpm -P /tmp GPG key is used to ensure the authenticity of the downloaded package during the installation process. If the key is not found, the installation step would fail. Use the commands below to download and import the GPG key. wget https://github.com/GluuFederation/flex/files/11814579/automation-flex-public-gpg.zip unzip automation-flex-public-gpg.zip sudo rpm -import automation-flex-public-gpg.asc Verify the integrity of the downloaded package using published sha256sum . Download the sha256sum file for the package wget https://github.com/GluuFederation/flex/releases/download/vreplace-flex-version/flex-replace-flex-version-el8.x86_64.rpm.sha256sum -P /tmp Run the command below from the directory where the downloaded package and the .sha256sum files are located. cd /tmp ; sha256sum -c flex-replace-flex-version-el8.x86_64.rpm.sha256sum ; Output similar to below should confirm the integrity of the downloaded package. flex-replace-flex-version-el8.x86_64.rpm : ok","title":"Download and Verify the Release Package"},{"location":"install/vm-install/rhel/#install-the-release-package","text":"sudo yum install ./flex-replace-flex-version-el8.x86_64.rpm","title":"Install the Release Package"},{"location":"install/vm-install/rhel/#run-the-setup-script","text":"Execute the setup script with command below: sudo python3 /opt/jans/jans-setup/flex/flex-linux-setup/flex_setup.py If Admin-UI component is being installed, then the script will require SSA input, either as text or as a file path. This should be the SSA or file which was acquired as part of prerequisite step . Install Admin UI [Y/n]: y Please enter path of file containing SSA or paste SSA (q to exit): Alternatively, for SSA file can be passed as a parameter to the setup script as below. python3 /opt/jans/jans-setup/flex/flex-linux-setup/flex_setup.py -admin-ui-ssa [ filename ]","title":"Run the setup script"},{"location":"install/vm-install/rhel/#verify-and-access-the-installation","text":"Verify that installation has been successful and all installed components are accessible using the steps below Log in to Text User Interface (TUI) /opt/jans/jans-cli/jans_cli_tui.py Full TUI documentation can be found here Log into Admin-UI using URI below https://FQDN/admin When troubleshooting issues with Admin UI access, it's advisable to check the logs , refer to the FAQ , and review service dependencies for potential solutions. Access Casa using URI below https://FQDN/jans-casa","title":"Verify and Access the Installation"},{"location":"install/vm-install/rhel/#enabling-https","text":"To enable communication with Janssen Server over TLS (https) in a production environment, Janssen Server needs details about CA certificate. Update the HTTPS cofiguration file https_jans.conf as shown below: Note Want to use Let's Encrypt to get a certificate? Follow this guide . Open https_jans.conf sudo vi /etc/httpd/conf.d/https_jans.conf Update SSLCertificateFile and SSLCertificateKeyFile parameters values SSLCertificateFile location_of_fullchain.pem SSLCertificateKeyFile location_of_privkey.pem Restart httpd service for changes to take effect sudo service httpd restart","title":"Enabling HTTPS"},{"location":"install/vm-install/rhel/#uninstallation","text":"Removing Flex is a two step process: Uninstall Gluu Flex Uninstall Janssen Packages If you have not run the setup script, you can skip step 1 and just remove the package.","title":"Uninstallation"},{"location":"install/vm-install/rhel/#uninstall-gluu-flex","text":"Use the command below to uninstall the Gluu Flex server sudo python3 /opt/jans/jans-setup/flex/flex-linux-setup/flex_setup.py --remove-flex Output: [ec2-user@manojs1978-lenient-drum ~]$ sudo python3 /opt/jans/jans-setup/flex/flex-linux-setup/flex_setup.py --remove-flex This process is irreversible. Gluu Flex Components will be removed Are you sure to uninstall Gluu Flex? [yes/N] yes Profile was detected as jans. Log Files: /opt/jans/jans-setup/logs/flex-setup.log /opt/jans/jans-setup/logs/flex-setup-error.log /opt/jans/jans-setup/setup_app/pylib/jwt/utils.py:7: CryptographyDeprecationWarning: Python 3.6 is no longer supported by the Python core team. Therefore, support for it is deprecated in cryptography and will be removed in a future release. from cryptography.hazmat.primitives.asymmetric.ec import EllipticCurve Please wait while collecting properties... Uninstalling Gluu Casa - Deleting /etc/default/casa - Deleting /etc/systemd/system/casa.service - Removing casa directives from apache configuration - Deleting /opt/jans/jetty/jans-auth/custom/libs/casa-config.jar - Removing plugin /opt/jans/jetty/jans-auth/custom/libs/casa-config.jar from Jans Auth Configuration - Deleting /opt/jans/python/libs/Casa.py - Deleting /opt/jans/python/libs/casa-external_fido2.py - Deleting /opt/jans/python/libs/casa-external_otp.py - Deleting /opt/jans/python/libs/casa-external_super_gluu.py - Deleting /opt/jans/python/libs/casa-external_twilio_sms.py - Deleting casa client from db backend - Deleting casa client scopes from db backend - Deleting casa configuration from db backend - Deleting script 3000-F75A from db backend - Deleting /opt/jans/jetty/casa Uninstalling Gluu Admin-UI - Deleting Gluu Flex Admin UI Client 2001.931e814d-01e2-4983-898f-91bf93670f7b - Removing Admin UI directives from apache configuration - Deleting /opt/jans/jetty/jans-config-api/custom/libs/gluu-flex-admin-ui-plugin.jar - Removing plugin /opt/jans/jetty/jans-config-api/custom/libs/gluu-flex-admin-ui-plugin.jar from Jans Config API Configuration - Deleting /opt/jans/jetty/jans-config-api/custom/config/log4j2-adminui.xml - Deleting /opt/jans/jetty/jans-config-api/custom/config/log4j2.xml - Rewriting Jans CLI init file for plugins - Deleting /var/www/html/admin Disabling script A51E-76DA Restarting Apache Restarting Jans Auth Restarting Janssen Config Api","title":"Uninstall Gluu Flex"},{"location":"install/vm-install/rhel/#uninstall-janssen-packages","text":"The command below removes and uninstall the jans package sudo python3 /opt/jans/jans-setup/install.py -uninstall Output: [ec2-user@manojs1978-lenient-drum ~]$ sudo python3 /opt/jans/jans-setup/install.py -uninstall This process is irreversible. You will lose all data related to Janssen Server. Are you sure to uninstall Janssen Server? [yes/N] yes Uninstalling Jannsen Server... Removing /etc/default/jans-config-api Stopping jans-config-api Removing /etc/default/jans-auth Stopping jans-auth Removing /etc/default/jans-fido2 Stopping jans-fido2 Removing /etc/default/jans-scim Stopping jans-scim Removing /etc/default/jans-cache-refresh Stopping jans-cache-refresh Executing rm -r -f /etc/certs Executing rm -r -f /etc/jans Executing rm -r -f /opt/jans Executing rm -r -f /opt/amazon-corretto* Executing rm -r -f /opt/jre Executing rm -r -f /opt/node* Executing rm -r -f /opt/jetty* Executing rm -r -f /opt/jython* Executing rm -r -f /opt/dist Removing /etc/httpd/conf.d/https_jans.conf","title":"Uninstall Janssen Packages"},{"location":"install/vm-install/rhel/#remove-gluu-flex-packages","text":"List existing Gluu packages with: sudo yum list installed | grep flex Remove packages: sudo yum remove ","title":"Remove Gluu Flex Packages:"},{"location":"install/vm-install/rhel/#uninstalling-admin-ui","text":"To uninstall the Admin UI from your Flex installation, execute this command: sudo python3 /opt/jans/jans-setup/flex/flex-linux-setup/flex_setup.py --remove-flex","title":"Uninstalling Admin UI"},{"location":"install/vm-install/rhel/#updating-admin-ui","text":"To update the Admin UI in an existing Flex installation, execute this command: sudo python3 /opt/jans/jans-setup/flex/flex-linux-setup/flex_setup.py --update-admin-ui","title":"Updating Admin UI"},{"location":"install/vm-install/suse/","tags":["administration","installation","vm","SUSE","SLES","Tumbleweed"],"text":"Install Gluu Flex On SUSE Linux # This is a step-by-step guide for installation and uninstallation of Gluu Flex on SUSE Linux distributions Prerequisites # Ensure that the OS platform is one of the supported versions VM should meet VM system requirements Make sure that if SELinux is installed then it is put into permissive mode If the server firewall is running, make sure you allow https , which is needed for OpenID and FIDO. sudo firewall-cmd --permanent --zone = public --add-service = https sudo firewall-cmd --reload for SUSE Linux Enterprise(SLES) we need to enable PackageHub as per OS version and architecture sudo SUSEConnect -p PackageHub/15.4/x86_64 Please obtain an SSA to trial Flex, after which you are issued a JWT that you can use during installation. SSA should be stored in a text file on an accessible path. Install the Package # Download and Verify the Release Package # Download the release package from the GitHub FLEX Releases wget https://github.com/GluuFederation/flex/releases/download/vreplace-flex-version/flex-replace-flex-version-suse15.x86_64.rpm -P ~/ GPG key is used to ensure the authenticity of the downloaded package during the installation process. If the key is not found, the installation step would fail. Use the commands below to download and import the GPG key. wget https://github.com/GluuFederation/flex/files/11814579/automation-flex-public-gpg.zip unzip automation-flex-public-gpg.zip sudo rpm -import automation-flex-public-gpg.asc Verify the integrity of the downloaded package using published sha256sum . Download the sha256sum file for the package wget https://github.com/GluuFederation/flex/releases/download/vreplace-flex-version/flex-replace-flex-version-suse15.x86_64.rpm.sha256sum -P ~/ Verify package integrity sha256sum -c flex-replace-flex-version-suse15.x86_64.rpm.sha256sum You should see: flex-replace-flex-version-suse15.x86_64.rpm: ok Install the Release Package # Use SUSE zypper to install sudo zypper install ~/flex-replace-flex-version-suse15.x86_64.rpm Run the setup script # Run the setup script: Execute the setup script with command below: sudo python3 /opt/jans/jans-setup/flex/flex-linux-setup/flex_setup.py If Admin-UI component is being installed, then the script will require SSA input, either as text or as a file path. This should be the SSA or file which was acquired as part of prerequisite step . Install Admin UI [Y/n]: y Please enter path of file containing SSA or paste SSA (q to exit): Alternatively, for SSA file can be passed as a parameter to the setup script as below. sudo python3 /opt/jans/jans-setup/flex/flex-linux-setup/flex_setup.py -admin-ui-ssa [ filename ] Verify and Access the Installation # Verify that installation has been successful and all installed components are accessible using the steps below: Log in to Text User Interface (TUI) /opt/jans/jans-cli/jans_cli_tui.py TUI is a text-based configuration tool for Gluu Flex Server. Log into Admin-UI using URI below https://FQDN/admin When troubleshooting issues with Admin UI access, it's advisable to check the logs , refer to the FAQ , and review service dependencies for potential solutions. Access Casa using URI below https://FQDN/jans-casa Enabling HTTPS # To enable communication with Janssen Server over TLS (https) in a production environment, Janssen Server needs details about CA certificate. Update the HTTPS cofiguration file https_jans.conf as shown below: Note Want to use Let's Encrypt to get a certificate? Follow this guide . Open _https_jans.conf sudo vi /etc/apache2/vhosts.d/_https_jans.conf ``` - Update ` SSLCertificateFile ` and ` SSLCertificateKeyFile ` parameters values ``` bash SSLCertificateFile location_of_fullchain.pem SSLCertificateKeyFile location_of_privkey.pem Restart apache service for changes to take effect sudo /usr/sbin/rcapache2 restart Uninstallation # Removing Flex is a two step process: Uninstall Gluu Flex and Uninstall Janssen Packages Remove Gluu Packages If you have not run the setup script, you can skip step 1 and just remove the package. First use the command below to uninstall the Gluu Flex server sudo python3 /opt/jans/jans-setup/flex/flex-linux-setup/flex_setup.py --remove-flex the output will be like this: sudo python3 /opt/jans/jans-setup/flex/flex-linux-setup/flex_setup.py --remove-flex This process is irreversible. Gluu Flex Components will be removed Are you sure to uninstall Gluu Flex? [yes/N] yes Profile was detected as jans. Log Files: /opt/jans/jans-setup/logs/flex-setup.log /opt/jans/jans-setup/logs/flex-setup-error.log /opt/jans/jans-setup/setup_app/pylib/jwt/utils.py:7: CryptographyDeprecationWarning: Python 3.6 is no longer supported by the Python core team. Therefore, support for it is deprecated in cryptography and will be removed in a future release. from cryptography.hazmat.primitives.asymmetric.ec import EllipticCurve Please wait while collecting properties... Uninstalling Gluu Casa - Deleting /etc/default/casa - Deleting /etc/systemd/system/casa.service - Removing casa directives from apache configuration - Deleting /opt/jans/jetty/jans-auth/custom/libs/casa-config.jar - Removing plugin /opt/jans/jetty/jans-auth/custom/libs/casa-config.jar from Jans Auth Configuration - Deleting /opt/jans/python/libs/Casa.py - Deleting /opt/jans/python/libs/casa-external_fido2.py - Deleting /opt/jans/python/libs/casa-external_otp.py - Deleting /opt/jans/python/libs/casa-external_super_gluu.py - Deleting /opt/jans/python/libs/casa-external_twilio_sms.py - Deleting casa client from db backend - Deleting casa client scopes from db backend - Deleting casa configuration from db backend - Deleting script 3000-F75A from db backend - Deleting /opt/jans/jetty/casa Uninstalling Gluu Admin-UI - Deleting Gluu Flex Admin UI Client 2001.732c7b51-57c4-48a5-b64d-8718b3e043bb - Removing Admin UI directives from apache configuration - Deleting /opt/jans/jetty/jans-config-api/custom/libs/gluu-flex-admin-ui-plugin.jar - Removing plugin /opt/jans/jetty/jans-config-api/custom/libs/gluu-flex-admin-ui-plugin.jar from Jans Config API Configuration - Deleting /opt/jans/jetty/jans-config-api/custom/config/log4j2-adminui.xml - Deleting /opt/jans/jetty/jans-config-api/custom/config/log4j2.xml - Rewriting Jans CLI init file for plugins - Deleting /srv/www/htdocs/admin Disabling script A51E-76DA Restarting Apache Restarting Jans Auth Restarting Janssen Config Api Uninstall Janssen Packages # The command below removes and uninstall the jans package sudo python3 /opt/jans/jans-setup/install.py -uninstall output will be like this: sudo python3 /opt/jans/jans-setup/install.py -uninstall -yes --keep-downloads --keep-setup This process is irreversible. You will lose all data related to Janssen Server. Are you sure to uninstall Janssen Server? [ yes/N ] yes Uninstalling Jannsen Server... Removing /etc/default/jans-config-api Stopping jans-config-api Removing /etc/default/jans-auth Stopping jans-auth Removing /etc/default/jans-fido2 Stopping jans-fido2 Removing /etc/default/jans-scim Stopping jans-scim Removing /etc/default/jans-cache-refresh Stopping jans-cache-refresh Executing rm -r -f /etc/certs Executing rm -r -f /etc/jans Executing rm -r -f /opt/jans Executing rm -r -f /opt/amazon-corretto* Executing rm -r -f /opt/jre Executing rm -r -f /opt/node* Executing rm -r -f /opt/jetty* Executing rm -r -f /opt/jython* Executing rm -r -f /opt/dist Removing /etc/apache2/vhosts.d/_https_jans.conf Second uninstall the package: You should see the package with: sudo rpm -qa | grep flex Remove package with: sudo zypper remove flex Updating Admin UI # To update the Admin UI in an existing Flex installation, execute this command: sudo python3 /opt/jans/jans-setup/flex/flex-linux-setup/flex_setup.py --update-admin-ui","title":"SUSE"},{"location":"install/vm-install/suse/#install-gluu-flex-on-suse-linux","text":"This is a step-by-step guide for installation and uninstallation of Gluu Flex on SUSE Linux distributions","title":"Install Gluu Flex On SUSE Linux"},{"location":"install/vm-install/suse/#prerequisites","text":"Ensure that the OS platform is one of the supported versions VM should meet VM system requirements Make sure that if SELinux is installed then it is put into permissive mode If the server firewall is running, make sure you allow https , which is needed for OpenID and FIDO. sudo firewall-cmd --permanent --zone = public --add-service = https sudo firewall-cmd --reload for SUSE Linux Enterprise(SLES) we need to enable PackageHub as per OS version and architecture sudo SUSEConnect -p PackageHub/15.4/x86_64 Please obtain an SSA to trial Flex, after which you are issued a JWT that you can use during installation. SSA should be stored in a text file on an accessible path.","title":"Prerequisites"},{"location":"install/vm-install/suse/#install-the-package","text":"","title":"Install the Package"},{"location":"install/vm-install/suse/#download-and-verify-the-release-package","text":"Download the release package from the GitHub FLEX Releases wget https://github.com/GluuFederation/flex/releases/download/vreplace-flex-version/flex-replace-flex-version-suse15.x86_64.rpm -P ~/ GPG key is used to ensure the authenticity of the downloaded package during the installation process. If the key is not found, the installation step would fail. Use the commands below to download and import the GPG key. wget https://github.com/GluuFederation/flex/files/11814579/automation-flex-public-gpg.zip unzip automation-flex-public-gpg.zip sudo rpm -import automation-flex-public-gpg.asc Verify the integrity of the downloaded package using published sha256sum . Download the sha256sum file for the package wget https://github.com/GluuFederation/flex/releases/download/vreplace-flex-version/flex-replace-flex-version-suse15.x86_64.rpm.sha256sum -P ~/ Verify package integrity sha256sum -c flex-replace-flex-version-suse15.x86_64.rpm.sha256sum You should see: flex-replace-flex-version-suse15.x86_64.rpm: ok","title":"Download and Verify the Release Package"},{"location":"install/vm-install/suse/#install-the-release-package","text":"Use SUSE zypper to install sudo zypper install ~/flex-replace-flex-version-suse15.x86_64.rpm","title":"Install the Release Package"},{"location":"install/vm-install/suse/#run-the-setup-script","text":"Run the setup script: Execute the setup script with command below: sudo python3 /opt/jans/jans-setup/flex/flex-linux-setup/flex_setup.py If Admin-UI component is being installed, then the script will require SSA input, either as text or as a file path. This should be the SSA or file which was acquired as part of prerequisite step . Install Admin UI [Y/n]: y Please enter path of file containing SSA or paste SSA (q to exit): Alternatively, for SSA file can be passed as a parameter to the setup script as below. sudo python3 /opt/jans/jans-setup/flex/flex-linux-setup/flex_setup.py -admin-ui-ssa [ filename ]","title":"Run the setup script"},{"location":"install/vm-install/suse/#verify-and-access-the-installation","text":"Verify that installation has been successful and all installed components are accessible using the steps below: Log in to Text User Interface (TUI) /opt/jans/jans-cli/jans_cli_tui.py TUI is a text-based configuration tool for Gluu Flex Server. Log into Admin-UI using URI below https://FQDN/admin When troubleshooting issues with Admin UI access, it's advisable to check the logs , refer to the FAQ , and review service dependencies for potential solutions. Access Casa using URI below https://FQDN/jans-casa","title":"Verify and Access the Installation"},{"location":"install/vm-install/suse/#enabling-https","text":"To enable communication with Janssen Server over TLS (https) in a production environment, Janssen Server needs details about CA certificate. Update the HTTPS cofiguration file https_jans.conf as shown below: Note Want to use Let's Encrypt to get a certificate? Follow this guide . Open _https_jans.conf sudo vi /etc/apache2/vhosts.d/_https_jans.conf ``` - Update ` SSLCertificateFile ` and ` SSLCertificateKeyFile ` parameters values ``` bash SSLCertificateFile location_of_fullchain.pem SSLCertificateKeyFile location_of_privkey.pem Restart apache service for changes to take effect sudo /usr/sbin/rcapache2 restart","title":"Enabling HTTPS"},{"location":"install/vm-install/suse/#uninstallation","text":"Removing Flex is a two step process: Uninstall Gluu Flex and Uninstall Janssen Packages Remove Gluu Packages If you have not run the setup script, you can skip step 1 and just remove the package. First use the command below to uninstall the Gluu Flex server sudo python3 /opt/jans/jans-setup/flex/flex-linux-setup/flex_setup.py --remove-flex the output will be like this: sudo python3 /opt/jans/jans-setup/flex/flex-linux-setup/flex_setup.py --remove-flex This process is irreversible. Gluu Flex Components will be removed Are you sure to uninstall Gluu Flex? [yes/N] yes Profile was detected as jans. Log Files: /opt/jans/jans-setup/logs/flex-setup.log /opt/jans/jans-setup/logs/flex-setup-error.log /opt/jans/jans-setup/setup_app/pylib/jwt/utils.py:7: CryptographyDeprecationWarning: Python 3.6 is no longer supported by the Python core team. Therefore, support for it is deprecated in cryptography and will be removed in a future release. from cryptography.hazmat.primitives.asymmetric.ec import EllipticCurve Please wait while collecting properties... Uninstalling Gluu Casa - Deleting /etc/default/casa - Deleting /etc/systemd/system/casa.service - Removing casa directives from apache configuration - Deleting /opt/jans/jetty/jans-auth/custom/libs/casa-config.jar - Removing plugin /opt/jans/jetty/jans-auth/custom/libs/casa-config.jar from Jans Auth Configuration - Deleting /opt/jans/python/libs/Casa.py - Deleting /opt/jans/python/libs/casa-external_fido2.py - Deleting /opt/jans/python/libs/casa-external_otp.py - Deleting /opt/jans/python/libs/casa-external_super_gluu.py - Deleting /opt/jans/python/libs/casa-external_twilio_sms.py - Deleting casa client from db backend - Deleting casa client scopes from db backend - Deleting casa configuration from db backend - Deleting script 3000-F75A from db backend - Deleting /opt/jans/jetty/casa Uninstalling Gluu Admin-UI - Deleting Gluu Flex Admin UI Client 2001.732c7b51-57c4-48a5-b64d-8718b3e043bb - Removing Admin UI directives from apache configuration - Deleting /opt/jans/jetty/jans-config-api/custom/libs/gluu-flex-admin-ui-plugin.jar - Removing plugin /opt/jans/jetty/jans-config-api/custom/libs/gluu-flex-admin-ui-plugin.jar from Jans Config API Configuration - Deleting /opt/jans/jetty/jans-config-api/custom/config/log4j2-adminui.xml - Deleting /opt/jans/jetty/jans-config-api/custom/config/log4j2.xml - Rewriting Jans CLI init file for plugins - Deleting /srv/www/htdocs/admin Disabling script A51E-76DA Restarting Apache Restarting Jans Auth Restarting Janssen Config Api","title":"Uninstallation"},{"location":"install/vm-install/suse/#uninstall-janssen-packages","text":"The command below removes and uninstall the jans package sudo python3 /opt/jans/jans-setup/install.py -uninstall output will be like this: sudo python3 /opt/jans/jans-setup/install.py -uninstall -yes --keep-downloads --keep-setup This process is irreversible. You will lose all data related to Janssen Server. Are you sure to uninstall Janssen Server? [ yes/N ] yes Uninstalling Jannsen Server... Removing /etc/default/jans-config-api Stopping jans-config-api Removing /etc/default/jans-auth Stopping jans-auth Removing /etc/default/jans-fido2 Stopping jans-fido2 Removing /etc/default/jans-scim Stopping jans-scim Removing /etc/default/jans-cache-refresh Stopping jans-cache-refresh Executing rm -r -f /etc/certs Executing rm -r -f /etc/jans Executing rm -r -f /opt/jans Executing rm -r -f /opt/amazon-corretto* Executing rm -r -f /opt/jre Executing rm -r -f /opt/node* Executing rm -r -f /opt/jetty* Executing rm -r -f /opt/jython* Executing rm -r -f /opt/dist Removing /etc/apache2/vhosts.d/_https_jans.conf Second uninstall the package: You should see the package with: sudo rpm -qa | grep flex Remove package with: sudo zypper remove flex","title":"Uninstall Janssen Packages"},{"location":"install/vm-install/suse/#updating-admin-ui","text":"To update the Admin UI in an existing Flex installation, execute this command: sudo python3 /opt/jans/jans-setup/flex/flex-linux-setup/flex_setup.py --update-admin-ui","title":"Updating Admin UI"},{"location":"install/vm-install/ubuntu/","tags":["administration","installation","vm","Ubuntu"],"text":"Install Gluu Flex On Ubuntu Linux # This is a step-by-step guide for installation and uninstallation of Gluu Flex on Ubuntu Linux Prerequisites # Ensure that the OS platform is one of the supported versions VM should meet VM system requirements Make sure that if SELinux is installed then it is put into permissive mode If the server firewall is running, make sure you allow https , which is needed for OpenID and FIDO. sudo ufw allow https Please obtain an SSA to trial Flex, after which you are issued a JWT that you can use during installation. SSA should be stored in a text file on an accessible path. Install the Package # Download and Verify the Release Package # Download the release package from the GitHub FLEX Releases . Choose the correct command from below based on the OS version. #Ubuntu 22.04 wget https://github.com/GluuFederation/flex/releases/download/vreplace-flex-version/flex_replace-flex-version.ubuntu22.04_amd64.deb -P /tmp #Ubuntu 20.04 wget https://github.com/GluuFederation/flex/releases/download/vreplace-flex-version/flex_replace-flex-version.ubuntu20.04_amd64.deb -P /tmp GPG key is used to ensure the authenticity of the downloaded package during the installation process. If the key is not found, the installation step would fail. Use the commands below to download and import the GPG key. wget https://github.com/GluuFederation/flex/files/11814579/automation-flex-public-gpg.zip unzip automation-flex-public-gpg.zip ; sudo gpg --import automation-flex-public-gpg.asc ; Verify the integrity of the downloaded package using published sha256sum . Download the sha256sum file for the package. Choose the correct command from below based on the OS version. #Ubuntu 22.04 wget https://github.com/GluuFederation/flex/releases/download/vreplace-flex-version/flex_replace-flex-version.ubuntu22.04_amd64.deb.sha256sum -P /tmp #Ubuntu 20.04 wget https://github.com/GluuFederation/flex/releases/download/vreplace-flex-version/flex_replace-flex-version.ubuntu20.04_amd64.deb.sha256sum -P /tmp Verify package integrity of the package that has been downloaded by checking hash. Run the command below from the directory where the downloaded package and the .sha256sum files are located. Choose the correct command from below based on the OS version. #Ubuntu 22.04 cd /tmp sha256sum -c flex_replace-flex-version.ubuntu22.04_amd64.deb.sha256sum #Ubuntu 20.04 cd /tmp sha256sum -c flex_replace-flex-version.ubuntu20.04_amd64.deb.sha256sum Output similar to below should confirm the integrity of the downloaded package. flex_replace-flex-version.ubuntu_amd64.deb: ok Install the Release Package # Choose the correct command from below based on the OS version. #Ubuntu 22.04 apt install -y /tmp/flex_replace-flex-version.ubuntu22.04_amd64.deb #Ubuntu 20.04 apt install -y /tmp/flex_replace-flex-version.ubuntu20.04_amd64.deb Run the setup script # Execute the setup script with command below: sudo python3 /opt/jans/jans-setup/flex/flex-linux-setup/flex_setup.py If Admin-UI component is being installed, then the script will require SSA input, either as text or as a file path. This should be the SSA or file which was acquired as part of prerequisite step . Install Admin UI [Y/n]: y Please enter path of file containing SSA or paste SSA (q to exit): Alternatively, for SSA file can be passed as a parameter to the setup script as below. sudo python3 /opt/jans/jans-setup/flex/flex-linux-setup/flex_setup.py -admin-ui-ssa [ filename ] Verify and Access the Installation # Verify that installation has been successful and all installed components are accessible using the steps below: Log in to Text User Interface (TUI) /opt/jans/jans-cli/jans_cli_tui.py TUI is a text-based configuration tool for Gluu Flex Server. Log into Admin-UI using URI below https://FQDN/admin When troubleshooting issues with Admin UI access, it's advisable to check the logs , refer to the FAQ , and review service dependencies for potential solutions. Access Casa using URI below https://FQDN/jans-casa Enabling HTTPS # To enable communication with Janssen Server over TLS (https) in a production environment, Janssen Server needs details about CA certificate. Note Want to use Let's Encrypt to get a certificate? Follow this guide . Uninstallation # Removing Flex is a two step process: Uninstall Gluu Flex Uninstall Janssen Packages If you have not run the setup script, you can skip step 1 and just remove the package. Uninstall Gluu Flex # Use the command below to uninstall the Gluu Flex server python3 /opt/jans/jans-setup/flex/flex-linux-setup/flex_setup.py --remove-flex Output: root@manojs1978-cute-ram:~# python3 /opt/jans/jans-setup/flex/flex-linux-setup/flex_setup.py --remove-flex This process is irreversible. Gluu Flex Components will be removed Are you sure to uninstall Gluu Flex? [yes/N] yes Profile was detected as jans. Log Files: /opt/jans/jans-setup/logs/flex-setup.log /opt/jans/jans-setup/logs/flex-setup-error.log Please wait while collecting properties... Uninstalling Gluu Casa - Deleting /etc/default/casa - Deleting /etc/systemd/system/casa.service - Removing casa directives from apache configuration - Deleting /opt/jans/jetty/jans-auth/custom/libs/casa-config.jar - Removing plugin /opt/jans/jetty/jans-auth/custom/libs/casa-config.jar from Jans Auth Configuration - Deleting /opt/jans/python/libs/Casa.py - Deleting /opt/jans/python/libs/casa-external_fido2.py - Deleting /opt/jans/python/libs/casa-external_otp.py - Deleting /opt/jans/python/libs/casa-external_super_gluu.py - Deleting /opt/jans/python/libs/casa-external_twilio_sms.py - Deleting casa client from db backend - Deleting casa client scopes from db backend - Deleting casa configuration from db backend - Deleting script 3000-F75A from db backend - Deleting /opt/jans/jetty/casa Uninstalling Gluu Admin-UI - Deleting Gluu Flex Admin UI Client 2001.e7989c7e-09b5-4e39-a7c9-a78017127cf0 - Removing Admin UI directives from apache configuration - Deleting /opt/jans/jetty/jans-config-api/custom/libs/gluu-flex-admin-ui-plugin.jar - Removing plugin /opt/jans/jetty/jans-config-api/custom/libs/gluu-flex-admin-ui-plugin.jar from Jans Config API Configuration - Deleting /opt/jans/jetty/jans-config-api/custom/config/log4j2-adminui.xml - Deleting /opt/jans/jetty/jans-config-api/custom/config/log4j2.xml - Rewriting Jans CLI init file for plugins - Deleting /var/www/html/admin Disabling script A51E-76DA Restarting Apache Restarting Jans Auth Restarting Janssen Config Api Uninstall Janssen Packages # The command below removes and uninstall the jans package python3 /opt/jans/jans-setup/install.py -uninstall Output : root@manojs1978-cute-ram:~# python3 /opt/jans/jans-setup/install.py -uninstall This process is irreversible. You will lose all data related to Janssen Server. Are you sure to uninstall Janssen Server? [yes/N] yes Uninstalling Jannsen Server... Removing /etc/default/jans-config-api Stopping jans-config-api Removing /etc/default/jans-auth Stopping jans-auth Removing /etc/default/jans-fido2 Stopping jans-fido2 Removing /etc/default/jans-scim Stopping jans-scim Removing /etc/default/jans-cache-refresh Stopping jans-cache-refresh Stopping OpenDj Server Stopping Server... [23/Jun/2023:09:10:27 +0000] category=BACKEND severity=NOTICE msgID=370 msg=The backend userRoot is now taken offline [23/Jun/2023:09:10:28 +0000] category=BACKEND severity=NOTICE msgID=370 msg=The backend site is now taken offline [23/Jun/2023:09:10:28 +0000] category=BACKEND severity=NOTICE msgID=370 msg=The backend metric is now taken offline [23/Jun/2023:09:10:28 +0000] category=CORE severity=NOTICE msgID=203 msg=The Directory Server is now stopped Executing rm -r -f /etc/certs Executing rm -r -f /etc/jans Executing rm -r -f /opt/jans Executing rm -r -f /opt/amazon-corretto* Executing rm -r -f /opt/jre Executing rm -r -f /opt/node* Executing rm -r -f /opt/jetty* Executing rm -r -f /opt/jython* Executing rm -r -f /opt/opendj Executing rm -r -f /opt/dist Removing /etc/apache2/sites-enabled/https_jans.conf Removing /etc/apache2/sites-available/https_jans.conf Remove Gluu Flex Packages: # List existing Gluu Flex packages with: sudo apt list --installed | grep flex Remove packages: sudo apt remove Uninstalling Admin UI # To uninstall the Admin UI from your Flex installation, execute this command: sudo python3 /opt/jans/jans-setup/flex/flex-linux-setup/flex_setup.py --remove-flex Updating Admin UI # To update the Admin UI in an existing Flex installation, execute this command: sudo python3 /opt/jans/jans-setup/flex/flex-linux-setup/flex_setup.py --update-admin-ui","title":"Ubuntu"},{"location":"install/vm-install/ubuntu/#install-gluu-flex-on-ubuntu-linux","text":"This is a step-by-step guide for installation and uninstallation of Gluu Flex on Ubuntu Linux","title":"Install Gluu Flex On Ubuntu Linux"},{"location":"install/vm-install/ubuntu/#prerequisites","text":"Ensure that the OS platform is one of the supported versions VM should meet VM system requirements Make sure that if SELinux is installed then it is put into permissive mode If the server firewall is running, make sure you allow https , which is needed for OpenID and FIDO. sudo ufw allow https Please obtain an SSA to trial Flex, after which you are issued a JWT that you can use during installation. SSA should be stored in a text file on an accessible path.","title":"Prerequisites"},{"location":"install/vm-install/ubuntu/#install-the-package","text":"","title":"Install the Package"},{"location":"install/vm-install/ubuntu/#download-and-verify-the-release-package","text":"Download the release package from the GitHub FLEX Releases . Choose the correct command from below based on the OS version. #Ubuntu 22.04 wget https://github.com/GluuFederation/flex/releases/download/vreplace-flex-version/flex_replace-flex-version.ubuntu22.04_amd64.deb -P /tmp #Ubuntu 20.04 wget https://github.com/GluuFederation/flex/releases/download/vreplace-flex-version/flex_replace-flex-version.ubuntu20.04_amd64.deb -P /tmp GPG key is used to ensure the authenticity of the downloaded package during the installation process. If the key is not found, the installation step would fail. Use the commands below to download and import the GPG key. wget https://github.com/GluuFederation/flex/files/11814579/automation-flex-public-gpg.zip unzip automation-flex-public-gpg.zip ; sudo gpg --import automation-flex-public-gpg.asc ; Verify the integrity of the downloaded package using published sha256sum . Download the sha256sum file for the package. Choose the correct command from below based on the OS version. #Ubuntu 22.04 wget https://github.com/GluuFederation/flex/releases/download/vreplace-flex-version/flex_replace-flex-version.ubuntu22.04_amd64.deb.sha256sum -P /tmp #Ubuntu 20.04 wget https://github.com/GluuFederation/flex/releases/download/vreplace-flex-version/flex_replace-flex-version.ubuntu20.04_amd64.deb.sha256sum -P /tmp Verify package integrity of the package that has been downloaded by checking hash. Run the command below from the directory where the downloaded package and the .sha256sum files are located. Choose the correct command from below based on the OS version. #Ubuntu 22.04 cd /tmp sha256sum -c flex_replace-flex-version.ubuntu22.04_amd64.deb.sha256sum #Ubuntu 20.04 cd /tmp sha256sum -c flex_replace-flex-version.ubuntu20.04_amd64.deb.sha256sum Output similar to below should confirm the integrity of the downloaded package. flex_replace-flex-version.ubuntu_amd64.deb: ok","title":"Download and Verify the Release Package"},{"location":"install/vm-install/ubuntu/#install-the-release-package","text":"Choose the correct command from below based on the OS version. #Ubuntu 22.04 apt install -y /tmp/flex_replace-flex-version.ubuntu22.04_amd64.deb #Ubuntu 20.04 apt install -y /tmp/flex_replace-flex-version.ubuntu20.04_amd64.deb","title":"Install the Release Package"},{"location":"install/vm-install/ubuntu/#run-the-setup-script","text":"Execute the setup script with command below: sudo python3 /opt/jans/jans-setup/flex/flex-linux-setup/flex_setup.py If Admin-UI component is being installed, then the script will require SSA input, either as text or as a file path. This should be the SSA or file which was acquired as part of prerequisite step . Install Admin UI [Y/n]: y Please enter path of file containing SSA or paste SSA (q to exit): Alternatively, for SSA file can be passed as a parameter to the setup script as below. sudo python3 /opt/jans/jans-setup/flex/flex-linux-setup/flex_setup.py -admin-ui-ssa [ filename ]","title":"Run the setup script"},{"location":"install/vm-install/ubuntu/#verify-and-access-the-installation","text":"Verify that installation has been successful and all installed components are accessible using the steps below: Log in to Text User Interface (TUI) /opt/jans/jans-cli/jans_cli_tui.py TUI is a text-based configuration tool for Gluu Flex Server. Log into Admin-UI using URI below https://FQDN/admin When troubleshooting issues with Admin UI access, it's advisable to check the logs , refer to the FAQ , and review service dependencies for potential solutions. Access Casa using URI below https://FQDN/jans-casa","title":"Verify and Access the Installation"},{"location":"install/vm-install/ubuntu/#enabling-https","text":"To enable communication with Janssen Server over TLS (https) in a production environment, Janssen Server needs details about CA certificate. Note Want to use Let's Encrypt to get a certificate? Follow this guide .","title":"Enabling HTTPS"},{"location":"install/vm-install/ubuntu/#uninstallation","text":"Removing Flex is a two step process: Uninstall Gluu Flex Uninstall Janssen Packages If you have not run the setup script, you can skip step 1 and just remove the package.","title":"Uninstallation"},{"location":"install/vm-install/ubuntu/#uninstall-gluu-flex","text":"Use the command below to uninstall the Gluu Flex server python3 /opt/jans/jans-setup/flex/flex-linux-setup/flex_setup.py --remove-flex Output: root@manojs1978-cute-ram:~# python3 /opt/jans/jans-setup/flex/flex-linux-setup/flex_setup.py --remove-flex This process is irreversible. Gluu Flex Components will be removed Are you sure to uninstall Gluu Flex? [yes/N] yes Profile was detected as jans. Log Files: /opt/jans/jans-setup/logs/flex-setup.log /opt/jans/jans-setup/logs/flex-setup-error.log Please wait while collecting properties... Uninstalling Gluu Casa - Deleting /etc/default/casa - Deleting /etc/systemd/system/casa.service - Removing casa directives from apache configuration - Deleting /opt/jans/jetty/jans-auth/custom/libs/casa-config.jar - Removing plugin /opt/jans/jetty/jans-auth/custom/libs/casa-config.jar from Jans Auth Configuration - Deleting /opt/jans/python/libs/Casa.py - Deleting /opt/jans/python/libs/casa-external_fido2.py - Deleting /opt/jans/python/libs/casa-external_otp.py - Deleting /opt/jans/python/libs/casa-external_super_gluu.py - Deleting /opt/jans/python/libs/casa-external_twilio_sms.py - Deleting casa client from db backend - Deleting casa client scopes from db backend - Deleting casa configuration from db backend - Deleting script 3000-F75A from db backend - Deleting /opt/jans/jetty/casa Uninstalling Gluu Admin-UI - Deleting Gluu Flex Admin UI Client 2001.e7989c7e-09b5-4e39-a7c9-a78017127cf0 - Removing Admin UI directives from apache configuration - Deleting /opt/jans/jetty/jans-config-api/custom/libs/gluu-flex-admin-ui-plugin.jar - Removing plugin /opt/jans/jetty/jans-config-api/custom/libs/gluu-flex-admin-ui-plugin.jar from Jans Config API Configuration - Deleting /opt/jans/jetty/jans-config-api/custom/config/log4j2-adminui.xml - Deleting /opt/jans/jetty/jans-config-api/custom/config/log4j2.xml - Rewriting Jans CLI init file for plugins - Deleting /var/www/html/admin Disabling script A51E-76DA Restarting Apache Restarting Jans Auth Restarting Janssen Config Api","title":"Uninstall Gluu Flex"},{"location":"install/vm-install/ubuntu/#uninstall-janssen-packages","text":"The command below removes and uninstall the jans package python3 /opt/jans/jans-setup/install.py -uninstall Output : root@manojs1978-cute-ram:~# python3 /opt/jans/jans-setup/install.py -uninstall This process is irreversible. You will lose all data related to Janssen Server. Are you sure to uninstall Janssen Server? [yes/N] yes Uninstalling Jannsen Server... Removing /etc/default/jans-config-api Stopping jans-config-api Removing /etc/default/jans-auth Stopping jans-auth Removing /etc/default/jans-fido2 Stopping jans-fido2 Removing /etc/default/jans-scim Stopping jans-scim Removing /etc/default/jans-cache-refresh Stopping jans-cache-refresh Stopping OpenDj Server Stopping Server... [23/Jun/2023:09:10:27 +0000] category=BACKEND severity=NOTICE msgID=370 msg=The backend userRoot is now taken offline [23/Jun/2023:09:10:28 +0000] category=BACKEND severity=NOTICE msgID=370 msg=The backend site is now taken offline [23/Jun/2023:09:10:28 +0000] category=BACKEND severity=NOTICE msgID=370 msg=The backend metric is now taken offline [23/Jun/2023:09:10:28 +0000] category=CORE severity=NOTICE msgID=203 msg=The Directory Server is now stopped Executing rm -r -f /etc/certs Executing rm -r -f /etc/jans Executing rm -r -f /opt/jans Executing rm -r -f /opt/amazon-corretto* Executing rm -r -f /opt/jre Executing rm -r -f /opt/node* Executing rm -r -f /opt/jetty* Executing rm -r -f /opt/jython* Executing rm -r -f /opt/opendj Executing rm -r -f /opt/dist Removing /etc/apache2/sites-enabled/https_jans.conf Removing /etc/apache2/sites-available/https_jans.conf","title":"Uninstall Janssen Packages"},{"location":"install/vm-install/ubuntu/#remove-gluu-flex-packages","text":"List existing Gluu Flex packages with: sudo apt list --installed | grep flex Remove packages: sudo apt remove ","title":"Remove Gluu Flex Packages:"},{"location":"install/vm-install/ubuntu/#uninstalling-admin-ui","text":"To uninstall the Admin UI from your Flex installation, execute this command: sudo python3 /opt/jans/jans-setup/flex/flex-linux-setup/flex_setup.py --remove-flex","title":"Uninstalling Admin UI"},{"location":"install/vm-install/ubuntu/#updating-admin-ui","text":"To update the Admin UI in an existing Flex installation, execute this command: sudo python3 /opt/jans/jans-setup/flex/flex-linux-setup/flex_setup.py --update-admin-ui","title":"Updating Admin UI"},{"location":"install/vm-install/vm-requirements/","text":"VM System Requirements # Supported Versions # Gluu Flex currently provides packages for these Linux distros: Ubuntu (versions: 20.04 and 22.04) SUSE Distributions SUSE Linux Enterprise Server (SLES) 15 openSUSE Leap 15.5 openSUSE Tumbleweed RedHat Enterprise Linux (version: 8) Note This document is intended exclusively for dev and staging environments. For production deployment on a VM, refer to this documentation which utilizes Rancher and Helm deployments. Hardware Requirements # A single-VM deployment is where all services are running on one server. Although, the requirements can vary based on the size of the data and the required concurrency, the following guidelines can help you plan: 8 GB RAM 4 CPU 20 GB Disk Port Configuration # Gluu Flex requires the following ports to be open for incoming connections. Port Protocol Notes 443 TCP TLS/HTTP You may want to use a redirect on port 80 to 443, although it is not required. Of course you will also need some way to login to your server, but that is out of scope of these docs. Check your server firewall documentation to configure your firewall to allow https . Hostname / IP Address Configuration # It is recommended that you use a static ip address for Gluu Flex. Your server should also return the hostname for the hostname command, it's recommended that you add the hostname to the /etc/hosts file. File Descriptor Configuration (FD) # Like most database and Internet servers, you must have at least 65k file descriptors. If you don't, your server will hang. First, check the current file descriptor limit using command below. If the existing FD limit exceeds 65535, then you're good. # cat /proc/sys/fs/file-max If FD limit is less than 65535 (e.g. 1024), then follow the steps below to increase the value. 1) Set soft and hard limits by adding the following lines in the /etc/security/limits.conf file * soft nofile 65535 * hard nofile 262144 2) Add the following lines to /etc/pam.d/login if not already present session required pam_limits.so 3) Increase the FD limit in /proc/sys/fs/file-max echo 65535 > /proc/sys/fs/file-max** 4) Use the ulimit command to set the FD limit to the hard limit specified in /etc/security/limits.conf . If setting to hard limit doesn't work, then try to set it to the soft limit. ulimit -n 262144 5) Restart the system","title":"VM System Requirements"},{"location":"install/vm-install/vm-requirements/#vm-system-requirements","text":"","title":"VM System Requirements"},{"location":"install/vm-install/vm-requirements/#supported-versions","text":"Gluu Flex currently provides packages for these Linux distros: Ubuntu (versions: 20.04 and 22.04) SUSE Distributions SUSE Linux Enterprise Server (SLES) 15 openSUSE Leap 15.5 openSUSE Tumbleweed RedHat Enterprise Linux (version: 8) Note This document is intended exclusively for dev and staging environments. For production deployment on a VM, refer to this documentation which utilizes Rancher and Helm deployments.","title":"Supported Versions"},{"location":"install/vm-install/vm-requirements/#hardware-requirements","text":"A single-VM deployment is where all services are running on one server. Although, the requirements can vary based on the size of the data and the required concurrency, the following guidelines can help you plan: 8 GB RAM 4 CPU 20 GB Disk","title":"Hardware Requirements"},{"location":"install/vm-install/vm-requirements/#port-configuration","text":"Gluu Flex requires the following ports to be open for incoming connections. Port Protocol Notes 443 TCP TLS/HTTP You may want to use a redirect on port 80 to 443, although it is not required. Of course you will also need some way to login to your server, but that is out of scope of these docs. Check your server firewall documentation to configure your firewall to allow https .","title":"Port Configuration"},{"location":"install/vm-install/vm-requirements/#hostname-ip-address-configuration","text":"It is recommended that you use a static ip address for Gluu Flex. Your server should also return the hostname for the hostname command, it's recommended that you add the hostname to the /etc/hosts file.","title":"Hostname / IP Address Configuration"},{"location":"install/vm-install/vm-requirements/#file-descriptor-configuration-fd","text":"Like most database and Internet servers, you must have at least 65k file descriptors. If you don't, your server will hang. First, check the current file descriptor limit using command below. If the existing FD limit exceeds 65535, then you're good. # cat /proc/sys/fs/file-max If FD limit is less than 65535 (e.g. 1024), then follow the steps below to increase the value. 1) Set soft and hard limits by adding the following lines in the /etc/security/limits.conf file * soft nofile 65535 * hard nofile 262144 2) Add the following lines to /etc/pam.d/login if not already present session required pam_limits.so 3) Increase the FD limit in /proc/sys/fs/file-max echo 65535 > /proc/sys/fs/file-max** 4) Use the ulimit command to set the FD limit to the hard limit specified in /etc/security/limits.conf . If setting to hard limit doesn't work, then try to set it to the soft limit. ulimit -n 262144 5) Restart the system","title":"File Descriptor Configuration (FD)"},{"location":"openbanking/","text":"Gluu Open Banking Identity Platform # Overview # The Gluu Open Banking Identity Platform is a specific profile of the Gluu Server that is packaged and configured for certain use cases: Dynamic Client Registration using software statements Payment Authorization Identity - eKYC Client Initiated Authentication (mobile/out-of-band) Other services needed by enterprises--but not by banks--have been disabled. The goal is to reduce the security surface area to make the platform easy to deploy, easy to keep up to date, and easy to rollout new features with zero downtime. This is a cloud-native distribution. Cloud-native is essential for auto-scaling, high availability, and operational automation. For development and testing we also support its VM distribution, where the Installation Section has more details about it. This distribution of Gluu is based on the Linux Foundation Janssen Project at the Linux Foundation, the most certified OpenID Platform available. Components # Open Banking OpenID Provider : Based on the Janssen Auth-Server, this internet-facing component provides the FAPI OpenID Connect API for dynamic client registration, transaction authorization, and CIBA. Config API : Service which configures the OpenID Provider. The Client must present an access token authorized by a trusted issuer with certain scopes. Cloud Database : Database used to store configuration, client metadata, tokens, and other information required for the operation of the OpenID Provider. Open Banking API Gateway : An Internet facing gateway for the core open banking API, should enforce the presence of a token with certain scopes. Open Banking API : The core banking API. Internal Authentication and Consent Service : An OpenID Provider, SAML IDP, or another authentication service that provides access to actual customer information. This service may handle the consent, or delegate consent to another service. User Accounts : A database where the user account information is held Bank Regulatory Directory : This is hosted by the federation operator which publishes public key material and other metadata about participants in the open banking ecosystem. Fintech / Payment Processor : A service that wants to call the Open Banking API or to get data or to process a payment. PKI infrastructure # Cloud-Native Architecture #","title":"Overview"},{"location":"openbanking/#gluu-open-banking-identity-platform","text":"","title":"Gluu Open Banking Identity Platform"},{"location":"openbanking/#overview","text":"The Gluu Open Banking Identity Platform is a specific profile of the Gluu Server that is packaged and configured for certain use cases: Dynamic Client Registration using software statements Payment Authorization Identity - eKYC Client Initiated Authentication (mobile/out-of-band) Other services needed by enterprises--but not by banks--have been disabled. The goal is to reduce the security surface area to make the platform easy to deploy, easy to keep up to date, and easy to rollout new features with zero downtime. This is a cloud-native distribution. Cloud-native is essential for auto-scaling, high availability, and operational automation. For development and testing we also support its VM distribution, where the Installation Section has more details about it. This distribution of Gluu is based on the Linux Foundation Janssen Project at the Linux Foundation, the most certified OpenID Platform available.","title":"Overview"},{"location":"openbanking/#components","text":"Open Banking OpenID Provider : Based on the Janssen Auth-Server, this internet-facing component provides the FAPI OpenID Connect API for dynamic client registration, transaction authorization, and CIBA. Config API : Service which configures the OpenID Provider. The Client must present an access token authorized by a trusted issuer with certain scopes. Cloud Database : Database used to store configuration, client metadata, tokens, and other information required for the operation of the OpenID Provider. Open Banking API Gateway : An Internet facing gateway for the core open banking API, should enforce the presence of a token with certain scopes. Open Banking API : The core banking API. Internal Authentication and Consent Service : An OpenID Provider, SAML IDP, or another authentication service that provides access to actual customer information. This service may handle the consent, or delegate consent to another service. User Accounts : A database where the user account information is held Bank Regulatory Directory : This is hosted by the federation operator which publishes public key material and other metadata about participants in the open banking ecosystem. Fintech / Payment Processor : A service that wants to call the Open Banking API or to get data or to process a payment.","title":"Components"},{"location":"openbanking/#pki-infrastructure","text":"","title":"PKI infrastructure"},{"location":"openbanking/#cloud-native-architecture","text":"","title":"Cloud-Native Architecture"},{"location":"openbanking/configuration-instructions/","text":"Generate/install keys and certs for Gluu Open Banking Identity Platform # This section covers details about setting up the keys and certificates in Cloud-Native distribution. For MTLS keys, see the document that demonstrates enabling mTLS in nginx ingress . Remember, MTLS is needed not only for the TPPs to call the authorization and token endpoints for OpenID Connect flows, but also by clients that are calling the configuration API. Add/Update Custom Scripts: # To add or update custom scripts, you can use either jans-cli or curl . jans-cli in interactive mode, option 13 enables you to manage custom scripts. For more info, see the docs . jans-cli in command line argument mode is more conducive to scripting and automation. To display the available operations for custom scripts, use config-cli.py --info CustomScripts . See the docs for more info. To use curl see these docs Note: If using VM installation you can normally find jans-cli.py in the /opt/jans/jans-cli/ folder.","title":"Configuration Instructions"},{"location":"openbanking/configuration-instructions/#generateinstall-keys-and-certs-for-gluu-open-banking-identity-platform","text":"This section covers details about setting up the keys and certificates in Cloud-Native distribution. For MTLS keys, see the document that demonstrates enabling mTLS in nginx ingress . Remember, MTLS is needed not only for the TPPs to call the authorization and token endpoints for OpenID Connect flows, but also by clients that are calling the configuration API.","title":"Generate/install keys and certs for Gluu Open Banking Identity Platform"},{"location":"openbanking/configuration-instructions/#addupdate-custom-scripts","text":"To add or update custom scripts, you can use either jans-cli or curl . jans-cli in interactive mode, option 13 enables you to manage custom scripts. For more info, see the docs . jans-cli in command line argument mode is more conducive to scripting and automation. To display the available operations for custom scripts, use config-cli.py --info CustomScripts . See the docs for more info. To use curl see these docs Note: If using VM installation you can normally find jans-cli.py in the /opt/jans/jans-cli/ folder.","title":"Add/Update Custom Scripts:"},{"location":"openbanking/curl/","text":"Managing scripts with CURL # Curl Prerequisites # Gluu open banking distribution client-id client-secret client certificate client key Getting the prerequisites # Get a client id and its associated password. Here, we will use the client id and secret created for config-api. TESTCLIENT = $( kubectl get cm cn -n --template ={{ .data.jca_client_id }} ) TESTCLIENTSECRET = $( kubectl get secret cn -n --template ={{ .data.jca_client_pw }} | base64 -d ) client.crt and client.key are the certificate and key files respectively for MTLS. Use your ca.crt and ca.key that was provided during setup to generate as many client certificates and keys as needed. If you have an existing helm deployment, you can retrieve ca.crt and ca.key using the following commands: kubectl get secret cn -n --template ={{ .data.ssl_ca_cert }} | base64 -d > ca.crt kubectl get secret cn -n --template ={{ .data.ssl_ca_key }} | base64 -d > ca.key Generate client.crt and client.key files: openssl req -new -newkey rsa:4096 -keyout client.key -out client.csr -nodes -subj '/CN=Openbanking' openssl x509 -req -sha256 -days 365 -in client.csr -CA ca.crt -CAkey ca.key -set_serial 02 -out client.crt CURL operations # The curl commands to list, add, or update custom script require a token, so first call the token endpoint to get the token using: curl -u $TESTCLIENT : $TESTCLIENTSECRET https:///jans-auth/restv1/token -d \"grant_type=client_credentials&scope=https://jans.io/oauth/config/scripts.readonly\" --cert client.crt --key client.key Example: curl -u '1801.bdfae945-b31d-4d60-8e47-16518153215:rjHoLfjfsv2G2qzGEasd1651813aIXvCi61NU' https://bank.gluu.org/jans-auth/restv1/token -d \"grant_type=client_credentials&scope=https://jans.io/oauth/config/scripts.readonly\" --cert apr22.crt --key apr22.key { \"access_token\" : \"ad34ac-8f2d-4bec-aed3-343adasda2\" , \"scope\" : \"https://jans.io/oauth/config/scripts.readonly\" , \"token_type\" : \"bearer\" , \"expires_in\" :299 } Save the access_token for use in subsequent commands. Use different scope values as per the requirement: View scripts information: https://jans.io/oauth/config/scripts.readonly Manage scripts-related information: https://jans.io/oauth/config/scripts.write Delete scripts-related information: https://jans.io/oauth/config/scripts.delete Use the obtained access token to perform further operations on custom scripts as given in subsequent text: Use the following command to display details of all the available custom scripts: curl -X GET https:///jans-config-api/api/v1/config/scripts -H \"Accept: application/json\" -H \"Authorization:Bearer \" -H \"Content-Type: application/json\" Example: curl -X GET https://bank.gluu.org/jans-config-api/api/v1/config/scripts -H \"Accept: application/json\" -H \"Authorization:Bearer ad34ac-8f2d-4bec-aed3-343adasda2\" -H \"Content-Type: application/json\" The following command will add a new custom script (Obtain token with write scope) and if it is successful it will display the added script in JSON format. The scriptformat.json file has script details according to the custom script schema. It should have the entire script inside the scriptformat.json as a string value under the script field. Converting a multiline script into a string requires converting newlines into \\n. So curl is not a suitable choice for adding new script, jans-cli is a better option. curl -X POST \"https:///jans-config-api/api/v1/config/scripts\" -H \"Accept: application/json\" -H \"Authorization:Bearer \" -H \"Content-Type: application/json\" --data @/home/user/scriptformat.json Example: curl -X POST \"https://bank.gluu.org/jans-config-api/api/v1/config/scripts\" -H \"Accept: application/json\" -H \"Authorization:Bearer ad34ac-8f2d-4bec-aed3-343adasda2\" -H \"Content-Type: application/json\" --data @/home/user/scriptformat.json","title":"Managing scripts with CURL"},{"location":"openbanking/curl/#managing-scripts-with-curl","text":"","title":"Managing scripts with CURL"},{"location":"openbanking/curl/#curl-prerequisites","text":"Gluu open banking distribution client-id client-secret client certificate client key","title":"Curl Prerequisites"},{"location":"openbanking/curl/#getting-the-prerequisites","text":"Get a client id and its associated password. Here, we will use the client id and secret created for config-api. TESTCLIENT = $( kubectl get cm cn -n --template ={{ .data.jca_client_id }} ) TESTCLIENTSECRET = $( kubectl get secret cn -n --template ={{ .data.jca_client_pw }} | base64 -d ) client.crt and client.key are the certificate and key files respectively for MTLS. Use your ca.crt and ca.key that was provided during setup to generate as many client certificates and keys as needed. If you have an existing helm deployment, you can retrieve ca.crt and ca.key using the following commands: kubectl get secret cn -n --template ={{ .data.ssl_ca_cert }} | base64 -d > ca.crt kubectl get secret cn -n --template ={{ .data.ssl_ca_key }} | base64 -d > ca.key Generate client.crt and client.key files: openssl req -new -newkey rsa:4096 -keyout client.key -out client.csr -nodes -subj '/CN=Openbanking' openssl x509 -req -sha256 -days 365 -in client.csr -CA ca.crt -CAkey ca.key -set_serial 02 -out client.crt","title":"Getting the prerequisites"},{"location":"openbanking/curl/#curl-operations","text":"The curl commands to list, add, or update custom script require a token, so first call the token endpoint to get the token using: curl -u $TESTCLIENT : $TESTCLIENTSECRET https:///jans-auth/restv1/token -d \"grant_type=client_credentials&scope=https://jans.io/oauth/config/scripts.readonly\" --cert client.crt --key client.key Example: curl -u '1801.bdfae945-b31d-4d60-8e47-16518153215:rjHoLfjfsv2G2qzGEasd1651813aIXvCi61NU' https://bank.gluu.org/jans-auth/restv1/token -d \"grant_type=client_credentials&scope=https://jans.io/oauth/config/scripts.readonly\" --cert apr22.crt --key apr22.key { \"access_token\" : \"ad34ac-8f2d-4bec-aed3-343adasda2\" , \"scope\" : \"https://jans.io/oauth/config/scripts.readonly\" , \"token_type\" : \"bearer\" , \"expires_in\" :299 } Save the access_token for use in subsequent commands. Use different scope values as per the requirement: View scripts information: https://jans.io/oauth/config/scripts.readonly Manage scripts-related information: https://jans.io/oauth/config/scripts.write Delete scripts-related information: https://jans.io/oauth/config/scripts.delete Use the obtained access token to perform further operations on custom scripts as given in subsequent text: Use the following command to display details of all the available custom scripts: curl -X GET https:///jans-config-api/api/v1/config/scripts -H \"Accept: application/json\" -H \"Authorization:Bearer \" -H \"Content-Type: application/json\" Example: curl -X GET https://bank.gluu.org/jans-config-api/api/v1/config/scripts -H \"Accept: application/json\" -H \"Authorization:Bearer ad34ac-8f2d-4bec-aed3-343adasda2\" -H \"Content-Type: application/json\" The following command will add a new custom script (Obtain token with write scope) and if it is successful it will display the added script in JSON format. The scriptformat.json file has script details according to the custom script schema. It should have the entire script inside the scriptformat.json as a string value under the script field. Converting a multiline script into a string requires converting newlines into \\n. So curl is not a suitable choice for adding new script, jans-cli is a better option. curl -X POST \"https:///jans-config-api/api/v1/config/scripts\" -H \"Accept: application/json\" -H \"Authorization:Bearer \" -H \"Content-Type: application/json\" --data @/home/user/scriptformat.json Example: curl -X POST \"https://bank.gluu.org/jans-config-api/api/v1/config/scripts\" -H \"Accept: application/json\" -H \"Authorization:Bearer ad34ac-8f2d-4bec-aed3-343adasda2\" -H \"Content-Type: application/json\" --data @/home/user/scriptformat.json","title":"CURL operations"},{"location":"openbanking/install-cn/","text":"System Requirements # Use the listing below for a detailed estimation of the minimum required resources. The table contains the default resources recommendation per service. Depending on the use of each service the resources need may increase or decrease. Service CPU Unit RAM Disk Space Processor Type Required Auth-server 2.5 2.5GB N/A 64 Bit Yes config - job 0.5 0.5GB N/A 64 Bit Yes on fresh installs persistence - job 0.5 0.5GB N/A 64 Bit Yes on fresh installs nginx 1 1GB N/A 64 Bit Yes if not ALB or Istio config-api 1 1GB N/A 64 Bit No Installation # Install using Helm(production-ready) # The below certificates and keys are needed to complete the installation. Certificate / key Description OB Issuing CA Used in nginx as a certificate authority OB Root CA Used in nginx as a certificate authority OB Signing CA Used in nginx as a certificate authority OB AS Transport key Used for mTLS. This will also be added to the JVM OB AS Transport crt Used for mTLS. This will also be added to the JVM OB AS signing crt Added to the JVM. Used in SSA Validation OB AS signing key Added to the JVM. Used in SSA Validation OB transport truststore Used in SSA Validation. Generated from OB Root CA nd Issuing CA Based on the provider/platform you're using, you can follow the docs to install your platform prerequistes, nginx-ingress, and the yaml changes needed in override.yaml based on the Gluu persistence choosed. To enable mTLS in ingress-nginx, add the following to your override.yaml : nginx-ingress : ingress : additionalAnnotations : nginx.ingress.kubernetes.io/auth-tls-verify-client : \"optional\" nginx.ingress.kubernetes.io/auth-tls-secret : \"gluu/tls-ob-ca-certificates\" nginx.ingress.kubernetes.io/auth-tls-verify-depth : \"1\" nginx.ingress.kubernetes.io/auth-tls-pass-certificate-to-upstream : \"true\" Adding these annotations will enable client certificate authentication . Enable authServerProtectedToken and authServerProtectedRegister : global auth-server : ingress : authServerProtectedToken : true authServerProtectedRegister : true Enable HTTPS During fresh installation, the config-job checks if SSL certificates and keys are mounted as files. If no mounted files are found, it attempts to download SSL certificates from the FQDN supplied. If the download is successful, an empty key file is generated. If no mounted or downloaded files are found, it generates self-signed SSL certificates, CA certificates, and keys. certificates and keys of interest in https Notes web_https.crt (nginx) web server certificate. This is commonly referred to as server.crt web_https.key (nginx) web server key. This is commonly referred to as server.key web_https.csr (nginx) web server certificate signing request. This is commonly referred to as server.csr web_https_ca.crt Certificate authority certificate that signed/signs the web server certificate. web_https_ca.key Certificate authority key that signed/signs the web server certificate. Create a secret containing the OB CA certificates (issuing, root, and signing CAs) and the OB AS transport crt. For more information read here . cat web_https_ca.crt issuingca.crt rootca.crt signingca.crt >> ca.crt kubectl create secret generic tls-ob-ca-certificates -n gluu --from-file = tls.crt = web_https.crt --from-file = tls.key = web_https.key --from-file = ca.crt = ca.crt If you have an existing helm deployment, those secrets can be retrieved and then create using the following commands: kubectl get secret cn -n gluu --template ={{ .data.ssl_ca_cert }} | base64 -d > ca.crt kubectl get secret cn -n gluu --template ={{ .data.ssl_cert }} | base64 -d > server.crt kubectl get secret cn -n gluu --template ={{ .data.ssl_key }} | base64 -d > server.key kubectl create secret generic ca-secret -n gluu --from-file = tls.crt = server.crt --from-file = tls.key = server.key --from-file = ca.crt = ca.crt Inject OBIE signed certs, keys and uri: When using OBIE signed certificates and keys, there are many objects that can be injected. The certificate signing pem file i.e obsigning.pem , the signing key i.e obsigning-oajsdij8927123.key , the certificate transport pem file i.e obtransport.pem , the transport key i.e obtransport-sdfe4234234.key , the transport truststore p12 i.e ob-transport-truststore.p12 , and the jwks uri https://mykeystore.openbanking.wow/xxxxx/xxxxx.jwks . base64 encrypt all .pem and .key files. cat obsigning.pem | base64 | tr -d '\\n' > obsigningbase64.pem cat obsigning-oajsdij8927123.key | base64 | tr -d '\\n' > obsigningbase64.key cat obtransport.pem | base64 | tr -d '\\n' > obtransportbase64.pem cat obtransport-sdfe4234234.key | base64 | tr -d '\\n' > obtransportbase64.key Generate your transport truststore or convert it to .p12 format. Please name it as ob-transport-truststore.p12 cat obissuingca.pem obrootca.pem obsigningca.pem > transport-truststore.crt keytool -importcert -file transport-truststore.crt -keystore ob-transport-truststore.p12 -alias obkeystore base64 encrypt the ob-transport-truststore.p12 cat ob-transport-truststore.p12 | base64 | tr -d '\\n' > obtransporttruststorebase64.pem Add the kid as the alias for the JKS used for the OB AS external signing crt. This is a kid value.Used in SSA Validation, kid used while encoding a JWT sent to token URL i.e XkwIzWy44xWSlcWnMiEc8iq9s2G. This kid value should exist inside the jwks uri endpoint. Add those values to override.yaml : global : # -- Open banking external signing jwks uri. Used in SSA Validation. cnObExtSigningJwksUri : \"\" # -- Open banking external signing jwks AS certificate authority string. Used in SSA Validation. This must be encoded using base64.. Used when `.global.cnObExtSigningJwksUri` is set. cnObExtSigningJwksCrt : # -- Open banking external signing jwks AS key string. Used in SSA Validation. This must be encoded using base64. Used when `.global.cnObExtSigningJwksUri` is set. cnObExtSigningJwksKey : # -- Open banking external signing jwks AS key passphrase to unlock provided key. This must be encoded using base64. Used when `.global.cnObExtSigningJwksUri` is set. cnObExtSigningJwksKeyPassPhrase : # -- Open banking external signing AS Alias. This is a kid value. Used in SSA Validation, kid used while encoding a JWT sent to token URL i.e. XkwIzWy44xWSlcWnMiEc8iq9s2G cnObExtSigningAlias : # -- Open banking signing AS kid to force the AS to use a specific signing key. i.e. Wy44xWSlcWnMiEc8iq9s2G cnObStaticSigningKeyKid : # -- Open banking AS transport crt. Used in SSA Validation. This must be encoded using base64. cnObTransportCrt : # -- Open banking AS transport key. Used in SSA Validation. This must be encoded using base64. cnObTransportKey : # -- Open banking AS transport key passphrase to unlock AS transport key. This must be encoded using base64. cnObTransportKeyPassPhrase : # -- Open banking transport Alias used inside the JVM. cnObTransportAlias : \"\" # -- Open banking AS transport truststore crt. This is normally generated from the OB issuing CA, OB Root CA and Signing CA. Used when .global.cnObExtSigningJwksUri is set. Used in SSA Validation. This must be encoded using base64. cnObTransportTrustStore : Please note that the password for the keystores created can be fetched by executing the following command: kubectl get secret cn -n gluu --template={{.data.auth_openid_jks_pass}} | base64 -d The above password is needed in custom scripts such as the Client Registration script After finishing all the tweaks to the override.yaml file, run helm install or helm upgrade if Gluu is already installed helm repo add gluu-flex https://docs.gluu.org/charts helm repo update helm install gluu gluu-flex/gluu -n gluu -f override.yaml Install on microK8s(development/testing) # sudo su - wget https://raw.githubusercontent.com/GluuFederation/flex/main/automation/startopenabankingdemo.sh && chmod u+x startopenabankingdemo.sh && ./startopenabankingdemo.sh Running this script will install the Gluu Open Banking Platform along with th mysql persistence. After running the script, you can go ahead and test the setup . Testing the setup # After successful installation, you can access and test the Gluu Open Banking Platform using either curl or Jans-CLI . Changing the signing key kid for the AS dynamically # Get a client id and its associated password. We will use the jans-config-api client id and secret TESTCLIENT = $( kubectl get cm cn -n gluu --template ={{ .data.jca_client_id }} ) TESTCLIENTSECRET = $( kubectl get secret cn -n gluu --template ={{ .data.jca_client_pw }} | base64 -d ) Get a token. To pass mTLS, we will use client.crt and client.key: curl -k -u $TESTCLIENT : $TESTCLIENTSECRET https:///jans-auth/restv1/token -d \"grant_type=client_credentials&scope=https://jans.io/oauth/jans-auth-server/config/properties.write\" --cert client.crt --key client.key Add the entry staticKid to force the AS to use a specific signing key. Please modify XhCYDfFM7UFXHfykNaLk1aLCnZM to the kid to be used: curl -k -X PATCH \"https:///jans-config-api/api/v1/jans-auth-server/config\" -H \"accept: application/json\" -H \"Content-Type: application/json-patch+json\" -H \"Authorization:Bearer 170e8412-1d55-4b19-ssss-8fcdeaafb954\" -d \"[{\\\"op\\\":\\\"add\\\",\\\"path\\\":\\\"/staticKid\\\",\\\"value\\\":\\\"XhCYDfFM7UFXHfykNaLk1aLCnZM\\\"}]\" Perform a rolling restart for the auth-server and config-api deployments. kubectl rollout restart deployment -auth-server -n gluu kubectl rollout restart deployment -config-api -n gluu Adding custom scopes upon installation # Download the original scopes file wget https://raw.githubusercontent.com/JanssenProject/docker-jans-persistence-loader/master/templates/scopes.ob.ldif Add to the file the custom scopes desired. Create a configmap with the scopes file kubectl create cm custom-scopes -n gluu --from-file=scopes.ob.ldif Mount the configmap in your override.yaml under persistence.volumes and persistence.volumeMounts persistence : volumes : - name : custom-scopes configMap : name : custom-scopes volumeMounts : - name : custom-scopes mountPath : \"/app/templates/scopes.ob.ldif\" subPath : scopes.ob.ldif Run helm install or helm upgrade if Gluu has already been installed.","title":"Cloud-Native"},{"location":"openbanking/install-cn/#system-requirements","text":"Use the listing below for a detailed estimation of the minimum required resources. The table contains the default resources recommendation per service. Depending on the use of each service the resources need may increase or decrease. Service CPU Unit RAM Disk Space Processor Type Required Auth-server 2.5 2.5GB N/A 64 Bit Yes config - job 0.5 0.5GB N/A 64 Bit Yes on fresh installs persistence - job 0.5 0.5GB N/A 64 Bit Yes on fresh installs nginx 1 1GB N/A 64 Bit Yes if not ALB or Istio config-api 1 1GB N/A 64 Bit No","title":"System Requirements"},{"location":"openbanking/install-cn/#installation","text":"","title":"Installation"},{"location":"openbanking/install-cn/#install-using-helmproduction-ready","text":"The below certificates and keys are needed to complete the installation. Certificate / key Description OB Issuing CA Used in nginx as a certificate authority OB Root CA Used in nginx as a certificate authority OB Signing CA Used in nginx as a certificate authority OB AS Transport key Used for mTLS. This will also be added to the JVM OB AS Transport crt Used for mTLS. This will also be added to the JVM OB AS signing crt Added to the JVM. Used in SSA Validation OB AS signing key Added to the JVM. Used in SSA Validation OB transport truststore Used in SSA Validation. Generated from OB Root CA nd Issuing CA Based on the provider/platform you're using, you can follow the docs to install your platform prerequistes, nginx-ingress, and the yaml changes needed in override.yaml based on the Gluu persistence choosed. To enable mTLS in ingress-nginx, add the following to your override.yaml : nginx-ingress : ingress : additionalAnnotations : nginx.ingress.kubernetes.io/auth-tls-verify-client : \"optional\" nginx.ingress.kubernetes.io/auth-tls-secret : \"gluu/tls-ob-ca-certificates\" nginx.ingress.kubernetes.io/auth-tls-verify-depth : \"1\" nginx.ingress.kubernetes.io/auth-tls-pass-certificate-to-upstream : \"true\" Adding these annotations will enable client certificate authentication . Enable authServerProtectedToken and authServerProtectedRegister : global auth-server : ingress : authServerProtectedToken : true authServerProtectedRegister : true Enable HTTPS During fresh installation, the config-job checks if SSL certificates and keys are mounted as files. If no mounted files are found, it attempts to download SSL certificates from the FQDN supplied. If the download is successful, an empty key file is generated. If no mounted or downloaded files are found, it generates self-signed SSL certificates, CA certificates, and keys. certificates and keys of interest in https Notes web_https.crt (nginx) web server certificate. This is commonly referred to as server.crt web_https.key (nginx) web server key. This is commonly referred to as server.key web_https.csr (nginx) web server certificate signing request. This is commonly referred to as server.csr web_https_ca.crt Certificate authority certificate that signed/signs the web server certificate. web_https_ca.key Certificate authority key that signed/signs the web server certificate. Create a secret containing the OB CA certificates (issuing, root, and signing CAs) and the OB AS transport crt. For more information read here . cat web_https_ca.crt issuingca.crt rootca.crt signingca.crt >> ca.crt kubectl create secret generic tls-ob-ca-certificates -n gluu --from-file = tls.crt = web_https.crt --from-file = tls.key = web_https.key --from-file = ca.crt = ca.crt If you have an existing helm deployment, those secrets can be retrieved and then create using the following commands: kubectl get secret cn -n gluu --template ={{ .data.ssl_ca_cert }} | base64 -d > ca.crt kubectl get secret cn -n gluu --template ={{ .data.ssl_cert }} | base64 -d > server.crt kubectl get secret cn -n gluu --template ={{ .data.ssl_key }} | base64 -d > server.key kubectl create secret generic ca-secret -n gluu --from-file = tls.crt = server.crt --from-file = tls.key = server.key --from-file = ca.crt = ca.crt Inject OBIE signed certs, keys and uri: When using OBIE signed certificates and keys, there are many objects that can be injected. The certificate signing pem file i.e obsigning.pem , the signing key i.e obsigning-oajsdij8927123.key , the certificate transport pem file i.e obtransport.pem , the transport key i.e obtransport-sdfe4234234.key , the transport truststore p12 i.e ob-transport-truststore.p12 , and the jwks uri https://mykeystore.openbanking.wow/xxxxx/xxxxx.jwks . base64 encrypt all .pem and .key files. cat obsigning.pem | base64 | tr -d '\\n' > obsigningbase64.pem cat obsigning-oajsdij8927123.key | base64 | tr -d '\\n' > obsigningbase64.key cat obtransport.pem | base64 | tr -d '\\n' > obtransportbase64.pem cat obtransport-sdfe4234234.key | base64 | tr -d '\\n' > obtransportbase64.key Generate your transport truststore or convert it to .p12 format. Please name it as ob-transport-truststore.p12 cat obissuingca.pem obrootca.pem obsigningca.pem > transport-truststore.crt keytool -importcert -file transport-truststore.crt -keystore ob-transport-truststore.p12 -alias obkeystore base64 encrypt the ob-transport-truststore.p12 cat ob-transport-truststore.p12 | base64 | tr -d '\\n' > obtransporttruststorebase64.pem Add the kid as the alias for the JKS used for the OB AS external signing crt. This is a kid value.Used in SSA Validation, kid used while encoding a JWT sent to token URL i.e XkwIzWy44xWSlcWnMiEc8iq9s2G. This kid value should exist inside the jwks uri endpoint. Add those values to override.yaml : global : # -- Open banking external signing jwks uri. Used in SSA Validation. cnObExtSigningJwksUri : \"\" # -- Open banking external signing jwks AS certificate authority string. Used in SSA Validation. This must be encoded using base64.. Used when `.global.cnObExtSigningJwksUri` is set. cnObExtSigningJwksCrt : # -- Open banking external signing jwks AS key string. Used in SSA Validation. This must be encoded using base64. Used when `.global.cnObExtSigningJwksUri` is set. cnObExtSigningJwksKey : # -- Open banking external signing jwks AS key passphrase to unlock provided key. This must be encoded using base64. Used when `.global.cnObExtSigningJwksUri` is set. cnObExtSigningJwksKeyPassPhrase : # -- Open banking external signing AS Alias. This is a kid value. Used in SSA Validation, kid used while encoding a JWT sent to token URL i.e. XkwIzWy44xWSlcWnMiEc8iq9s2G cnObExtSigningAlias : # -- Open banking signing AS kid to force the AS to use a specific signing key. i.e. Wy44xWSlcWnMiEc8iq9s2G cnObStaticSigningKeyKid : # -- Open banking AS transport crt. Used in SSA Validation. This must be encoded using base64. cnObTransportCrt : # -- Open banking AS transport key. Used in SSA Validation. This must be encoded using base64. cnObTransportKey : # -- Open banking AS transport key passphrase to unlock AS transport key. This must be encoded using base64. cnObTransportKeyPassPhrase : # -- Open banking transport Alias used inside the JVM. cnObTransportAlias : \"\" # -- Open banking AS transport truststore crt. This is normally generated from the OB issuing CA, OB Root CA and Signing CA. Used when .global.cnObExtSigningJwksUri is set. Used in SSA Validation. This must be encoded using base64. cnObTransportTrustStore : Please note that the password for the keystores created can be fetched by executing the following command: kubectl get secret cn -n gluu --template={{.data.auth_openid_jks_pass}} | base64 -d The above password is needed in custom scripts such as the Client Registration script After finishing all the tweaks to the override.yaml file, run helm install or helm upgrade if Gluu is already installed helm repo add gluu-flex https://docs.gluu.org/charts helm repo update helm install gluu gluu-flex/gluu -n gluu -f override.yaml","title":"Install using Helm(production-ready)"},{"location":"openbanking/install-cn/#install-on-microk8sdevelopmenttesting","text":"sudo su - wget https://raw.githubusercontent.com/GluuFederation/flex/main/automation/startopenabankingdemo.sh && chmod u+x startopenabankingdemo.sh && ./startopenabankingdemo.sh Running this script will install the Gluu Open Banking Platform along with th mysql persistence. After running the script, you can go ahead and test the setup .","title":"Install on microK8s(development/testing)"},{"location":"openbanking/install-cn/#testing-the-setup","text":"After successful installation, you can access and test the Gluu Open Banking Platform using either curl or Jans-CLI .","title":"Testing the setup"},{"location":"openbanking/install-cn/#changing-the-signing-key-kid-for-the-as-dynamically","text":"Get a client id and its associated password. We will use the jans-config-api client id and secret TESTCLIENT = $( kubectl get cm cn -n gluu --template ={{ .data.jca_client_id }} ) TESTCLIENTSECRET = $( kubectl get secret cn -n gluu --template ={{ .data.jca_client_pw }} | base64 -d ) Get a token. To pass mTLS, we will use client.crt and client.key: curl -k -u $TESTCLIENT : $TESTCLIENTSECRET https:///jans-auth/restv1/token -d \"grant_type=client_credentials&scope=https://jans.io/oauth/jans-auth-server/config/properties.write\" --cert client.crt --key client.key Add the entry staticKid to force the AS to use a specific signing key. Please modify XhCYDfFM7UFXHfykNaLk1aLCnZM to the kid to be used: curl -k -X PATCH \"https:///jans-config-api/api/v1/jans-auth-server/config\" -H \"accept: application/json\" -H \"Content-Type: application/json-patch+json\" -H \"Authorization:Bearer 170e8412-1d55-4b19-ssss-8fcdeaafb954\" -d \"[{\\\"op\\\":\\\"add\\\",\\\"path\\\":\\\"/staticKid\\\",\\\"value\\\":\\\"XhCYDfFM7UFXHfykNaLk1aLCnZM\\\"}]\" Perform a rolling restart for the auth-server and config-api deployments. kubectl rollout restart deployment -auth-server -n gluu kubectl rollout restart deployment -config-api -n gluu","title":"Changing the signing key kid for the AS dynamically"},{"location":"openbanking/install-cn/#adding-custom-scopes-upon-installation","text":"Download the original scopes file wget https://raw.githubusercontent.com/JanssenProject/docker-jans-persistence-loader/master/templates/scopes.ob.ldif Add to the file the custom scopes desired. Create a configmap with the scopes file kubectl create cm custom-scopes -n gluu --from-file=scopes.ob.ldif Mount the configmap in your override.yaml under persistence.volumes and persistence.volumeMounts persistence : volumes : - name : custom-scopes configMap : name : custom-scopes volumeMounts : - name : custom-scopes mountPath : \"/app/templates/scopes.ob.ldif\" subPath : scopes.ob.ldif Run helm install or helm upgrade if Gluu has already been installed.","title":"Adding custom scopes upon installation"},{"location":"openbanking/install-vm/","text":"VM Based Distribution # This section covers details on installing Gluu Openbanking Indentity Platform 1.0 in a VM. We recommend the Cloud Native Distribution for production environment. However, for development and testing VM distribution will be easier. VM Preparation # Prepare a VM with the following minimum specs: 4 GB RAM 2 GB swap space 2 CPU units 50 GB disk space The VM must have a static IP address and a resolvable hostname. A fully qualified domain name (FQDN) is required for production deployments. The Gluu Open Banking Identity Platform can be installed on main Linux distributions. Installation # Download the installer ( install.py ) wget https://raw.githubusercontent.com/JanssenProject/jans/main/jans-linux-setup/jans_setup/install.py Execute the installer: sudo python3 install.py --profile openbanking The installation script will install required tools, programs, packages and then it will prompt the user for setup instructions. Answer the following questions: Certificate Generation Setup # Prompt Description Enter IP Address The IP address for the VM. Use an IP address assigned to one of this server's network interfaces (usage of addresses assigned to loopback interfaces is not supported) Enter Hostname The hostname for the VM. Recommended to be a FQDN Enter your city or locality Used to generate X.509 certificates. Enter your state or province two letter code Used to generate X.509 certificates. Enter two letter Country Code Used to generate X.509 certificates. Enter Organization Name Used to generate X.509 certificates. Enter email address for support at your organization Used to generate X.509 certificates. Architecture Setup # Prompt Description Enter maximum RAM for applications in MB Maximum RAM Size in MB RDBM Type Backend type. Currently only MySQL is supported Use remote RDBM Select if connecting to an external MySQL server Enter Openbanking static kid The fallback key when key is not passed in requests (as required by Openbanking) Use external key If yes, link to an external Open Banking key file Before the last question installer process will display the selected choices and confirm to proceed. Prompt Description Proceed with these values [Y/n] Confirmation before setting up the services. Uninstalling Janssen Server # Execute the installation script with the -uninstall argument. MTLS Configuration # For MTLS, OBIE-issued (for openbanking UK) certificates and keys should be used. The following discussion assumes that the file ca.crt has a CA certificate and ca.key has a CA private key. Following command generates self-signed ca.crt and ca.key: openssl req -newkey rsa:2048 -nodes -keyform PEM -keyout ca.key -x509 -days 3650 -outform PEM -out ca.crt The following set of commands is an example of how to create the server\u2019s private key ( server.key ), Certificate Signing Request (CSR) ( server.csr ) and certificate ( server.crt) : openssl genrsa -out server.key 2048 openssl req -new -key server.key -out server.csr openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -set_serial 100 -days 365 -outform PEM -out server.crt Now, store the server key ( server.key ) and certificate ( server.crt ) file in some location (preferably inside /etc/certs ) and set its path in the apache .conf file ( /etc/apache2/sites-enabled/https_jans.conf ) with SSLCertificateFile and SSLCertificateKeyFile directives: SSLCertificateFile /etc/certs/bankgluu/server.crt SSLCertificateKeyFile /etc/certs/bankgluu/server.key The path of CA certificate file should be set to SSLCACertificateFile directive as: SSLCACertificateFile /etc/apache2/certs/matls.pem The following commands will create client\u2019s private key ( client.key ), CSR ( client.csr ) and certificate ( client.crt ): openssl genrsa -out client.key 2048 openssl req -new -key client.key -out client.csr openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key -set_serial 101 -days 365 -outform PEM -out client.crt The following command will create a client certification chain (private key, public certificate and ca certificate) into the file client.pem : cat client.key client.crt ca.crt >client.pem Use this pem file to create JWKs for the clients (if required). To create a JWK, you can use a free utility published at https://mkjwk.org . Or you can download the command-line tool from GitHub . There are numerous other online PEM-to-JWKS tools available like JWKConvertFunctions . We may need to add/update some data in these generated JWKs. Note It is important to give different values of the Common Name field (\u201cCommon Name (e.g. server FQDN or YOUR name) []\u201d) for the CA, Server and clients. Other fields may have common values but the same values for Common Name of all certificates result in certificate verification failing at runtime. Importing the CA certificate in JVM truststore and signing, encryption keys into auth-Server keystore: # The command line utility keytool is installed with JDK, it can be used to import the CA certificate in JVM truststore (/opt/jre/lib/security/cacerts) and signing,encryption keys into the jans-auth server\u2019s keystore(/etc/certs/jans-auth-keys.jks). ./keytool -importcert -file /path/to/file/filename.cer -keystore /etc/certs/jans-auth-keys.jks -alias yourkeystore ./keytool -importkeystore -srckeystore /path/to/file/filename.jks -srcstoretype JKS -destkeystore /opt/jre/lib/security/cacerts -deststoretype JKS Accessing the Platform # After successful installation, access the Gluu Open Banking Platform using either jans-cli or curl .","title":"VM (only recommended for development/testing)"},{"location":"openbanking/install-vm/#vm-based-distribution","text":"This section covers details on installing Gluu Openbanking Indentity Platform 1.0 in a VM. We recommend the Cloud Native Distribution for production environment. However, for development and testing VM distribution will be easier.","title":"VM Based Distribution"},{"location":"openbanking/install-vm/#vm-preparation","text":"Prepare a VM with the following minimum specs: 4 GB RAM 2 GB swap space 2 CPU units 50 GB disk space The VM must have a static IP address and a resolvable hostname. A fully qualified domain name (FQDN) is required for production deployments. The Gluu Open Banking Identity Platform can be installed on main Linux distributions.","title":"VM Preparation"},{"location":"openbanking/install-vm/#installation","text":"Download the installer ( install.py ) wget https://raw.githubusercontent.com/JanssenProject/jans/main/jans-linux-setup/jans_setup/install.py Execute the installer: sudo python3 install.py --profile openbanking The installation script will install required tools, programs, packages and then it will prompt the user for setup instructions. Answer the following questions:","title":"Installation"},{"location":"openbanking/install-vm/#certificate-generation-setup","text":"Prompt Description Enter IP Address The IP address for the VM. Use an IP address assigned to one of this server's network interfaces (usage of addresses assigned to loopback interfaces is not supported) Enter Hostname The hostname for the VM. Recommended to be a FQDN Enter your city or locality Used to generate X.509 certificates. Enter your state or province two letter code Used to generate X.509 certificates. Enter two letter Country Code Used to generate X.509 certificates. Enter Organization Name Used to generate X.509 certificates. Enter email address for support at your organization Used to generate X.509 certificates.","title":"Certificate Generation Setup"},{"location":"openbanking/install-vm/#architecture-setup","text":"Prompt Description Enter maximum RAM for applications in MB Maximum RAM Size in MB RDBM Type Backend type. Currently only MySQL is supported Use remote RDBM Select if connecting to an external MySQL server Enter Openbanking static kid The fallback key when key is not passed in requests (as required by Openbanking) Use external key If yes, link to an external Open Banking key file Before the last question installer process will display the selected choices and confirm to proceed. Prompt Description Proceed with these values [Y/n] Confirmation before setting up the services.","title":"Architecture Setup"},{"location":"openbanking/install-vm/#uninstalling-janssen-server","text":"Execute the installation script with the -uninstall argument.","title":"Uninstalling Janssen Server"},{"location":"openbanking/install-vm/#mtls-configuration","text":"For MTLS, OBIE-issued (for openbanking UK) certificates and keys should be used. The following discussion assumes that the file ca.crt has a CA certificate and ca.key has a CA private key. Following command generates self-signed ca.crt and ca.key: openssl req -newkey rsa:2048 -nodes -keyform PEM -keyout ca.key -x509 -days 3650 -outform PEM -out ca.crt The following set of commands is an example of how to create the server\u2019s private key ( server.key ), Certificate Signing Request (CSR) ( server.csr ) and certificate ( server.crt) : openssl genrsa -out server.key 2048 openssl req -new -key server.key -out server.csr openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -set_serial 100 -days 365 -outform PEM -out server.crt Now, store the server key ( server.key ) and certificate ( server.crt ) file in some location (preferably inside /etc/certs ) and set its path in the apache .conf file ( /etc/apache2/sites-enabled/https_jans.conf ) with SSLCertificateFile and SSLCertificateKeyFile directives: SSLCertificateFile /etc/certs/bankgluu/server.crt SSLCertificateKeyFile /etc/certs/bankgluu/server.key The path of CA certificate file should be set to SSLCACertificateFile directive as: SSLCACertificateFile /etc/apache2/certs/matls.pem The following commands will create client\u2019s private key ( client.key ), CSR ( client.csr ) and certificate ( client.crt ): openssl genrsa -out client.key 2048 openssl req -new -key client.key -out client.csr openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key -set_serial 101 -days 365 -outform PEM -out client.crt The following command will create a client certification chain (private key, public certificate and ca certificate) into the file client.pem : cat client.key client.crt ca.crt >client.pem Use this pem file to create JWKs for the clients (if required). To create a JWK, you can use a free utility published at https://mkjwk.org . Or you can download the command-line tool from GitHub . There are numerous other online PEM-to-JWKS tools available like JWKConvertFunctions . We may need to add/update some data in these generated JWKs. Note It is important to give different values of the Common Name field (\u201cCommon Name (e.g. server FQDN or YOUR name) []\u201d) for the CA, Server and clients. Other fields may have common values but the same values for Common Name of all certificates result in certificate verification failing at runtime.","title":"MTLS Configuration"},{"location":"openbanking/install-vm/#importing-the-ca-certificate-in-jvm-truststore-and-signing-encryption-keys-into-auth-server-keystore","text":"The command line utility keytool is installed with JDK, it can be used to import the CA certificate in JVM truststore (/opt/jre/lib/security/cacerts) and signing,encryption keys into the jans-auth server\u2019s keystore(/etc/certs/jans-auth-keys.jks). ./keytool -importcert -file /path/to/file/filename.cer -keystore /etc/certs/jans-auth-keys.jks -alias yourkeystore ./keytool -importkeystore -srckeystore /path/to/file/filename.jks -srcstoretype JKS -destkeystore /opt/jre/lib/security/cacerts -deststoretype JKS","title":"Importing the CA certificate in JVM truststore and signing, encryption keys into auth-Server keystore:"},{"location":"openbanking/install-vm/#accessing-the-platform","text":"After successful installation, access the Gluu Open Banking Platform using either jans-cli or curl .","title":"Accessing the Platform"},{"location":"openbanking/jans-cli/","text":"Introduction # Jans-cli is a command line interface to configure the Janssen software and it supports both interactive and command-line options for configuration. Jans-cli calls the Jans-Config-API to perform various operations. During Janssen installation, the installer creates a client to use Jans Config API. Jans-cli uses this client to call Jans Config API. Supported Operations # Jans-cli supports the following six operations on custom scripts: get-config-scripts : gets a list of custom scripts. post-config-scripts : adds a new custom script. put-config-scripts : updates a custom script. get-config-scripts-by-type : requires an argument --url-suffix TYPE: <> . You can specify the following types: PERSON_AUTHENTICATION , INTROSPECTION , RESOURCE_OWNER_PASSWORD_CREDENTIALS , APPLICATION_SESSION , CACHE_REFRESH , UPDATE_USER , USER_REGISTRATION , CLIENT_REGISTRATION , ID_GENERATOR , UMA_RPT_POLICY , UMA_RPT_CLAIMS , UMA_CLAIMS_GATHERING , CONSENT_GATHERING , DYNAMIC_SCOPE , SPONTANEOUS_SCOPE , END_SESSION , POST_AUTHN , SCIM , CIBA_END_USER_NOTIFICATION , PERSISTENCE_EXTENSION , IDP , or UPDATE_TOKEN . get-config-scripts-by-inum : requires an argument --url-suffix inum: <> delete-config-scripts-by-inum : requires an argument --url-suffix inum: <> Using jans-cli # Download jans-cli.pyz . This package can be built manually too. Get a client id and its associated password. Here, we will use the client id and secret created for config-api. TESTCLIENT = $( kubectl get cm cn -n --template ={{ .data.jca_client_id }} ) TESTCLIENTSECRET = $( kubectl get secret cn -n --template ={{ .data.jca_client_pw }} | base64 -d ) client.crt and client.key are the certificate and key files respectively for MTLS. We need to pass this certificate, key as the token endpoint is under MTLS and jans-cli obtains an appropriate token before performing the operation. Use your ca.crt and ca.key that was provided during setup to generate as many client certificates and keys for operating jans-cli as needed. If you have an existing helm deployment, you can retrieve ca.crt and ca.key using the following commands: kubectl get secret cn -n --template ={{ .data.ssl_ca_cert }} | base64 -d > ca.crt kubectl get secret cn -n --template ={{ .data.ssl_ca_key }} | base64 -d > ca.key Generate client.crt and client.key files: openssl req -new -newkey rsa:4096 -keyout client.key -out client.csr -nodes -subj '/CN=Openbanking' openssl x509 -req -sha256 -days 365 -in client.csr -CA ca.crt -CAkey ca.key -set_serial 02 -out client.crt Run the jans-cli in interactive mode and try it out: python3 jans-cli-linux-amd64.pyz --host --client-id $TESTCLIENT --client_secret $TESTCLIENTSECRET --CC client.crt --CK client.key Examples # The post-config-scripts and put-config-scripts require various details about the scripts. The following command gives the basic schema of the custom scripts to pass to these operations. python3 jans-cli-linux-amd64.pyz --host --client-id $TESTCLIENT --client_secret $TESTCLIENTSECRET --schema /components/schemas/CustomScript The output of the above command will be similar as: { \"dn\" : null , \"inum\" : null , \"name\" : \"string\" , \"aliases\" : [], \"description\" : null , \"script\" : \"string\" , \"scriptType\" : \"IDP\" , \"programmingLanguage\" : \"PYTHON\" , \"moduleProperties\" : { \"value1\" : null , \"value2\" : null , \"description\" : null }, \"configurationProperties\" : { \"value1\" : null , \"value2\" : null , \"description\" : null , \"hide\" : true }, \"level\" : \"integer\" , \"revision\" : 0 , \"enabled\" : false , \"scriptError\" : { \"raisedAt\" : null , \"stackTrace\" : null }, \"modified\" : false , \"internal\" : false } To add or modify a script first, we need to create the script's python file (e.g. /tmp/sample.py) and then create a JSON file by following the above schema and update the fields as : /tmp/sample.json { \"name\" : \"mySampleScript\" , \"aliases\" : null , \"description\" : \"This is a sample script\" , \"script\" : \"_file /tmp/sample.py\" , \"scriptType\" : \"PERSON_AUTHENTICATION\" , \"programmingLanguage\" : \"PYTHON\" , \"moduleProperties\" : [ { \"value1\" : \"mayvalue1\" , \"value2\" : \"myvalues2\" , \"description\" : \"description for property\" } ], \"configurationProperties\" : null , \"level\" : 1 , \"revision\" : 0 , \"enabled\" : false , \"scriptError\" : null , \"modified\" : false , \"internal\" : false } Add a new custom script, update and delete existing custom script # The following command will add a new script with details given in /tmp/sampleadd.json file. The jans-cli will generate a unique inum of this new script if we skip inum in the json file. python3 jans-cli-linux-amd64.pyz --host --client-id $TESTCLIENT --client_secret $TESTCLIENTSECRET --operation-id post-config-scripts --data /tmp/sampleadd.json \\ --CC client.crt --CK client.key The following command will modify/update the existing script with details given in /tmp/samplemodify.json file. Remember to set inum field in samplemodify.json to the inum of the script to update. python3 jans-cli-linux-amd64.pyz --host --client-id $TESTCLIENT --client_secret $TESTCLIENTSECRET --operation-id put-config-scripts --data /tmp/samplemodify.json \\ --CC client.crt --CK client.key To delete a custom script by its inum, use the following command: python3 jans-cli-linux-amd64.pyz --host --client-id $TESTCLIENT --client_secret $TESTCLIENTSECRET --operation-id delete-config-scripts-by-inum --url-suffix inum:HKM-TEST \\ --CC client.crt --CK client.key Print details of existing custom scripts # These commands to print the details are important, as using them we can get the inum of these scripts which is required to perform update or delete operations. The following command will display the details of all the existing custom scripts. This will be helpful to get the inum of scripts to perform the update and delete operation. python3 jans-cli-linux-amd64.pyz --host --client-id $TESTCLIENT --client_secret $TESTCLIENTSECRET --operation-id get-config-scripts --CC client.crt --CK client.key The following command displays the details of selected custom script (by inum). python3 jans-cli-linux-amd64.pyz --host --client-id $TESTCLIENT --client_secret $TESTCLIENTSECRET --operation-id get-config-scripts-by-inum --url-suffix inum:_____ \\ --CC client.crt --CK client.key Use the following command to display the details of existing custom scripts of a given type (for example: INTROSPECTION). python3 jans-cli-linux-amd64.pyz --host --client-id $TESTCLIENT --client_secret $TESTCLIENTSECRET --operation-id get-config-scripts-by-type --url-suffix type:INTROSPECTION \\ --CC client.crt --CK client.key","title":"Managing Scripts with the jans-cli"},{"location":"openbanking/jans-cli/#introduction","text":"Jans-cli is a command line interface to configure the Janssen software and it supports both interactive and command-line options for configuration. Jans-cli calls the Jans-Config-API to perform various operations. During Janssen installation, the installer creates a client to use Jans Config API. Jans-cli uses this client to call Jans Config API.","title":"Introduction"},{"location":"openbanking/jans-cli/#supported-operations","text":"Jans-cli supports the following six operations on custom scripts: get-config-scripts : gets a list of custom scripts. post-config-scripts : adds a new custom script. put-config-scripts : updates a custom script. get-config-scripts-by-type : requires an argument --url-suffix TYPE: <> . You can specify the following types: PERSON_AUTHENTICATION , INTROSPECTION , RESOURCE_OWNER_PASSWORD_CREDENTIALS , APPLICATION_SESSION , CACHE_REFRESH , UPDATE_USER , USER_REGISTRATION , CLIENT_REGISTRATION , ID_GENERATOR , UMA_RPT_POLICY , UMA_RPT_CLAIMS , UMA_CLAIMS_GATHERING , CONSENT_GATHERING , DYNAMIC_SCOPE , SPONTANEOUS_SCOPE , END_SESSION , POST_AUTHN , SCIM , CIBA_END_USER_NOTIFICATION , PERSISTENCE_EXTENSION , IDP , or UPDATE_TOKEN . get-config-scripts-by-inum : requires an argument --url-suffix inum: <> delete-config-scripts-by-inum : requires an argument --url-suffix inum: <>","title":"Supported Operations"},{"location":"openbanking/jans-cli/#using-jans-cli","text":"Download jans-cli.pyz . This package can be built manually too. Get a client id and its associated password. Here, we will use the client id and secret created for config-api. TESTCLIENT = $( kubectl get cm cn -n --template ={{ .data.jca_client_id }} ) TESTCLIENTSECRET = $( kubectl get secret cn -n --template ={{ .data.jca_client_pw }} | base64 -d ) client.crt and client.key are the certificate and key files respectively for MTLS. We need to pass this certificate, key as the token endpoint is under MTLS and jans-cli obtains an appropriate token before performing the operation. Use your ca.crt and ca.key that was provided during setup to generate as many client certificates and keys for operating jans-cli as needed. If you have an existing helm deployment, you can retrieve ca.crt and ca.key using the following commands: kubectl get secret cn -n --template ={{ .data.ssl_ca_cert }} | base64 -d > ca.crt kubectl get secret cn -n --template ={{ .data.ssl_ca_key }} | base64 -d > ca.key Generate client.crt and client.key files: openssl req -new -newkey rsa:4096 -keyout client.key -out client.csr -nodes -subj '/CN=Openbanking' openssl x509 -req -sha256 -days 365 -in client.csr -CA ca.crt -CAkey ca.key -set_serial 02 -out client.crt Run the jans-cli in interactive mode and try it out: python3 jans-cli-linux-amd64.pyz --host --client-id $TESTCLIENT --client_secret $TESTCLIENTSECRET --CC client.crt --CK client.key","title":"Using jans-cli"},{"location":"openbanking/jans-cli/#examples","text":"The post-config-scripts and put-config-scripts require various details about the scripts. The following command gives the basic schema of the custom scripts to pass to these operations. python3 jans-cli-linux-amd64.pyz --host --client-id $TESTCLIENT --client_secret $TESTCLIENTSECRET --schema /components/schemas/CustomScript The output of the above command will be similar as: { \"dn\" : null , \"inum\" : null , \"name\" : \"string\" , \"aliases\" : [], \"description\" : null , \"script\" : \"string\" , \"scriptType\" : \"IDP\" , \"programmingLanguage\" : \"PYTHON\" , \"moduleProperties\" : { \"value1\" : null , \"value2\" : null , \"description\" : null }, \"configurationProperties\" : { \"value1\" : null , \"value2\" : null , \"description\" : null , \"hide\" : true }, \"level\" : \"integer\" , \"revision\" : 0 , \"enabled\" : false , \"scriptError\" : { \"raisedAt\" : null , \"stackTrace\" : null }, \"modified\" : false , \"internal\" : false } To add or modify a script first, we need to create the script's python file (e.g. /tmp/sample.py) and then create a JSON file by following the above schema and update the fields as : /tmp/sample.json { \"name\" : \"mySampleScript\" , \"aliases\" : null , \"description\" : \"This is a sample script\" , \"script\" : \"_file /tmp/sample.py\" , \"scriptType\" : \"PERSON_AUTHENTICATION\" , \"programmingLanguage\" : \"PYTHON\" , \"moduleProperties\" : [ { \"value1\" : \"mayvalue1\" , \"value2\" : \"myvalues2\" , \"description\" : \"description for property\" } ], \"configurationProperties\" : null , \"level\" : 1 , \"revision\" : 0 , \"enabled\" : false , \"scriptError\" : null , \"modified\" : false , \"internal\" : false }","title":"Examples"},{"location":"openbanking/jans-cli/#add-a-new-custom-script-update-and-delete-existing-custom-script","text":"The following command will add a new script with details given in /tmp/sampleadd.json file. The jans-cli will generate a unique inum of this new script if we skip inum in the json file. python3 jans-cli-linux-amd64.pyz --host --client-id $TESTCLIENT --client_secret $TESTCLIENTSECRET --operation-id post-config-scripts --data /tmp/sampleadd.json \\ --CC client.crt --CK client.key The following command will modify/update the existing script with details given in /tmp/samplemodify.json file. Remember to set inum field in samplemodify.json to the inum of the script to update. python3 jans-cli-linux-amd64.pyz --host --client-id $TESTCLIENT --client_secret $TESTCLIENTSECRET --operation-id put-config-scripts --data /tmp/samplemodify.json \\ --CC client.crt --CK client.key To delete a custom script by its inum, use the following command: python3 jans-cli-linux-amd64.pyz --host --client-id $TESTCLIENT --client_secret $TESTCLIENTSECRET --operation-id delete-config-scripts-by-inum --url-suffix inum:HKM-TEST \\ --CC client.crt --CK client.key","title":"Add a new custom script, update and delete existing custom script"},{"location":"openbanking/jans-cli/#print-details-of-existing-custom-scripts","text":"These commands to print the details are important, as using them we can get the inum of these scripts which is required to perform update or delete operations. The following command will display the details of all the existing custom scripts. This will be helpful to get the inum of scripts to perform the update and delete operation. python3 jans-cli-linux-amd64.pyz --host --client-id $TESTCLIENT --client_secret $TESTCLIENTSECRET --operation-id get-config-scripts --CC client.crt --CK client.key The following command displays the details of selected custom script (by inum). python3 jans-cli-linux-amd64.pyz --host --client-id $TESTCLIENT --client_secret $TESTCLIENTSECRET --operation-id get-config-scripts-by-inum --url-suffix inum:_____ \\ --CC client.crt --CK client.key Use the following command to display the details of existing custom scripts of a given type (for example: INTROSPECTION). python3 jans-cli-linux-amd64.pyz --host --client-id $TESTCLIENT --client_secret $TESTCLIENTSECRET --operation-id get-config-scripts-by-type --url-suffix type:INTROSPECTION \\ --CC client.crt --CK client.key","title":"Print details of existing custom scripts"},{"location":"openbanking/par-jarm/","text":"Pushed Authorization Requests(PAR) and JWT Secured Authorization Response Mode(JARM) # This section covers details of two important features required by the open banking ecosystem. The latest Gluu Open Banking Identity Platform supports PAR and JARM specifications. These two features are bundled in the installation so when you install the Gluu Open Banking Identity Platform the Authorization Server(AS) will support these features by default. The older/existing installation may require updating the WAR/ image. Moreover, these features are also FAPI certified for Brazil Open Banking (Based on FAPI 1 Advanced Final) . Pushed Authorization Requests-PAR: # PAR are handled by an additional endpoint of Authorization Server (AS). Clients POST their authorization parameters to this endpoint, in return the clients gets a reference (named as request URI value) that will be used in further authorization requests by the client. PAR enables the OAuth clients to push the payload of an authorization request directly to the authorization server in exchange for a request URI value. This request URI value is used as a reference to the authorization request payload data in a subsequent call to the authorization endpoint. We can set different PAR lifetimes for different clients . PAR lifetime will be 600 seconds if it is unspecified . We have two new configuration properties for PAR: * parEndpoint - String , corresponds to pushed_authorization_request_endpoint as defined by specification . * requirePar - Boolean parameter indicating whether the only means of initiating an authorization request the client is allowed to use is a pushed authorization request . If omitted , the default value is \"false\" . Moreover, there is a new client configuration: * parLifetime: An integer parameter representing the lifetime (in seconds) of the pushed authorization request. JWT Secured Authorization Response Mode-JARM # This is a new JWT-based response mode to encode authorization responses known as JARM, (see Financial-grade API: JWT Secured Authorization Response Mode for OAuth 2.0 ). Here clients are enabled to request the transmission of the authorization response parameters along with additional data in JWT format. This mechanism enhances the security of the standard authorization response since it adds support for signing and encryption,sender authentication, and audience restriction. It also provides protection from replay, credential leakage, and mix-up attacks. It can be combined with any response type. For this feature AS supports new response modes ( query.jwt , fragment.jwt , form_post.jwt , jwt ) and additional signing, encryption algorithms.","title":"PAR and JARM"},{"location":"openbanking/par-jarm/#pushed-authorization-requestspar-and-jwt-secured-authorization-response-modejarm","text":"This section covers details of two important features required by the open banking ecosystem. The latest Gluu Open Banking Identity Platform supports PAR and JARM specifications. These two features are bundled in the installation so when you install the Gluu Open Banking Identity Platform the Authorization Server(AS) will support these features by default. The older/existing installation may require updating the WAR/ image. Moreover, these features are also FAPI certified for Brazil Open Banking (Based on FAPI 1 Advanced Final) .","title":"Pushed Authorization Requests(PAR) and JWT Secured Authorization Response Mode(JARM)"},{"location":"openbanking/par-jarm/#pushed-authorization-requests-par","text":"PAR are handled by an additional endpoint of Authorization Server (AS). Clients POST their authorization parameters to this endpoint, in return the clients gets a reference (named as request URI value) that will be used in further authorization requests by the client. PAR enables the OAuth clients to push the payload of an authorization request directly to the authorization server in exchange for a request URI value. This request URI value is used as a reference to the authorization request payload data in a subsequent call to the authorization endpoint. We can set different PAR lifetimes for different clients . PAR lifetime will be 600 seconds if it is unspecified . We have two new configuration properties for PAR: * parEndpoint - String , corresponds to pushed_authorization_request_endpoint as defined by specification . * requirePar - Boolean parameter indicating whether the only means of initiating an authorization request the client is allowed to use is a pushed authorization request . If omitted , the default value is \"false\" . Moreover, there is a new client configuration: * parLifetime: An integer parameter representing the lifetime (in seconds) of the pushed authorization request.","title":"Pushed Authorization Requests-PAR:"},{"location":"openbanking/par-jarm/#jwt-secured-authorization-response-mode-jarm","text":"This is a new JWT-based response mode to encode authorization responses known as JARM, (see Financial-grade API: JWT Secured Authorization Response Mode for OAuth 2.0 ). Here clients are enabled to request the transmission of the authorization response parameters along with additional data in JWT format. This mechanism enhances the security of the standard authorization response since it adds support for signing and encryption,sender authentication, and audience restriction. It also provides protection from replay, credential leakage, and mix-up attacks. It can be combined with any response type. For this feature AS supports new response modes ( query.jwt , fragment.jwt , form_post.jwt , jwt ) and additional signing, encryption algorithms.","title":"JWT Secured Authorization Response Mode-JARM"},{"location":"reference/","tags":["administration","reference"],"text":"Overview # The Gluu Flex reference guide includes technical references for Flex-specific components and deployments. References for Janssen components, including database references, can be found in the Janssen Project documentation .","title":"Overview"},{"location":"reference/#overview","text":"The Gluu Flex reference guide includes technical references for Flex-specific components and deployments. References for Janssen components, including database references, can be found in the Janssen Project documentation .","title":"Overview"},{"location":"reference/json-config/","text":"Where is this content? # The Gluu Flex documentation is a work in progress, and this document is currently a draft. Keep an eye on this page for updates.","title":"Index"},{"location":"reference/json-config/#where-is-this-content","text":"The Gluu Flex documentation is a work in progress, and this document is currently a draft. Keep an eye on this page for updates.","title":"Where is this content?"},{"location":"reference/json-config/properties/","text":"Where is this content? # The Gluu Flex documentation is a work in progress, and this document is currently a draft. Keep an eye on this page for updates.","title":"Index"},{"location":"reference/json-config/properties/#where-is-this-content","text":"The Gluu Flex documentation is a work in progress, and this document is currently a draft. Keep an eye on this page for updates.","title":"Where is this content?"},{"location":"reference/json-config/properties/casa-properties/","text":"Where is this content? # The Gluu Flex documentation is a work in progress, and this document is currently a draft. Keep an eye on this page for updates.","title":"Casa properties"},{"location":"reference/json-config/properties/casa-properties/#where-is-this-content","text":"The Gluu Flex documentation is a work in progress, and this document is currently a draft. Keep an eye on this page for updates.","title":"Where is this content?"},{"location":"reference/json-config/properties/casaconfig-properties/","text":"Where is this content? # The Gluu Flex documentation is a work in progress, and this document is currently a draft. Keep an eye on this page for updates.","title":"Casaconfig properties"},{"location":"reference/json-config/properties/casaconfig-properties/#where-is-this-content","text":"The Gluu Flex documentation is a work in progress, and this document is currently a draft. Keep an eye on this page for updates.","title":"Where is this content?"},{"location":"reference/kubernetes/","tags":["administration","reference","kubernetes","architecture","components"],"text":"Overview # This Reference guide helps you learn about the components and architecture of Gluu Flex. Gluu Flex components # auth-server : The OAuth Authorization Server, the OpenID Connect Provider, the UMA Authorization Server--this is the main Internet facing component of Janssen. It's the service that returns tokens, JWT's and identity assertions. This service must be Internet facing. auth-key-rotation : Responsible for regenerating auth-keys per x hours. config-api : The API to configure the auth-server and other components is consolidated in this component. This service should not be Internet-facing. Fido : Provides the server side endpoints to enroll and validate devices that use FIDO. It provides both FIDO U2F (register, authenticate) and FIDO 2 (attestation, assertion) endpoints. This service must be internet facing. SCIM : a JSON/REST API to manage user data. Use it to add, edit and update user information. This service should not be Internet facing. Casa : self-service web portal for end-users to manage authentication and authorization preferences for their account in a Gluu Server. Admin UI : The admin web portal to configure and control your Gluu server. Architectural diagram of Gluu #","title":"Overview"},{"location":"reference/kubernetes/#overview","text":"This Reference guide helps you learn about the components and architecture of Gluu Flex.","title":"Overview"},{"location":"reference/kubernetes/#gluu-flex-components","text":"auth-server : The OAuth Authorization Server, the OpenID Connect Provider, the UMA Authorization Server--this is the main Internet facing component of Janssen. It's the service that returns tokens, JWT's and identity assertions. This service must be Internet facing. auth-key-rotation : Responsible for regenerating auth-keys per x hours. config-api : The API to configure the auth-server and other components is consolidated in this component. This service should not be Internet-facing. Fido : Provides the server side endpoints to enroll and validate devices that use FIDO. It provides both FIDO U2F (register, authenticate) and FIDO 2 (attestation, assertion) endpoints. This service must be internet facing. SCIM : a JSON/REST API to manage user data. Use it to add, edit and update user information. This service should not be Internet facing. Casa : self-service web portal for end-users to manage authentication and authorization preferences for their account in a Gluu Server. Admin UI : The admin web portal to configure and control your Gluu server.","title":"Gluu Flex components"},{"location":"reference/kubernetes/#architectural-diagram-of-gluu","text":"","title":"Architectural diagram of Gluu"},{"location":"reference/kubernetes/docker-admin-ui/","tags":["administration","reference","kubernetes","docker image"],"text":"docker-admin-ui # A containerized application for Gluu Admin UI frontend. Versions # See Releases for stable versions. For bleeding-edge/unstable version, use gluufederation/admin-ui:1.0.0_dev . Environment Variables # The following environment variables are supported by the container: CN_CONFIG_ADAPTER : The config backend adapter, can be consul (default), kubernetes , or google . CN_CONFIG_CONSUL_HOST : hostname or IP of Consul (default to localhost ). CN_CONFIG_CONSUL_PORT : port of Consul (default to 8500 ). CN_CONFIG_CONSUL_CONSISTENCY : Consul consistency mode (choose one of default , consistent , or stale ). Default to stale mode. CN_CONFIG_CONSUL_SCHEME : supported Consul scheme ( http or https ). CN_CONFIG_CONSUL_VERIFY : whether to verify cert or not (default to false ). CN_CONFIG_CONSUL_CACERT_FILE : path to Consul CA cert file (default to /etc/certs/consul_ca.crt ). This file will be used if it exists and CN_CONFIG_CONSUL_VERIFY set to true . CN_CONFIG_CONSUL_CERT_FILE : path to Consul cert file (default to /etc/certs/consul_client.crt ). CN_CONFIG_CONSUL_KEY_FILE : path to Consul key file (default to /etc/certs/consul_client.key ). CN_CONFIG_CONSUL_TOKEN_FILE : path to file contains ACL token (default to /etc/certs/consul_token ). CN_CONFIG_KUBERNETES_NAMESPACE : Kubernetes namespace (default to default ). CN_CONFIG_KUBERNETES_CONFIGMAP : Kubernetes configmaps name (default to jans ). CN_CONFIG_KUBERNETES_USE_KUBE_CONFIG : Load credentials from $HOME/.kube/config , only useful for non-container environment (default to false ). CN_SECRET_ADAPTER : The secrets' adapter, can be vault (default), kubernetes , or google . CN_SECRET_VAULT_VERIFY : whether to verify cert or not (default to false ). CN_SECRET_VAULT_ROLE_ID_FILE : path to file contains Vault AppRole role ID (default to /etc/certs/vault_role_id ). CN_SECRET_VAULT_SECRET_ID_FILE : path to file contains Vault AppRole secret ID (default to /etc/certs/vault_secret_id ). CN_SECRET_VAULT_CERT_FILE : path to Vault cert file (default to /etc/certs/vault_client.crt ). CN_SECRET_VAULT_KEY_FILE : path to Vault key file (default to /etc/certs/vault_client.key ). CN_SECRET_VAULT_CACERT_FILE : path to Vault CA cert file (default to /etc/certs/vault_ca.crt ). This file will be used if it exists and CN_SECRET_VAULT_VERIFY set to true . CN_SECRET_VAULT_ADDR : URL of Vault (default to http://localhost:8200 ). CN_SECRET_VAULT_NAMESPACE : Namespace used to access secrets (default to empty string). CN_SECRET_VAULT_KV_PATH : Path to KV secrets engine (default to secret ). CN_SECRET_VAULT_PREFIX : Base prefix name used to build secret path (default to jans ). CN_SECRET_VAULT_APPROLE_PATH : Path to AppRole (default to approle ). CN_SECRET_KUBERNETES_NAMESPACE : Kubernetes namespace (default to default ). CN_SECRET_KUBERNETES_CONFIGMAP : Kubernetes secrets name (default to jans ). CN_SECRET_KUBERNETES_USE_KUBE_CONFIG : Load credentials from $HOME/.kube/config , only useful for non-container environment (default to false ). CN_WAIT_MAX_TIME : How long the startup \"health checks\" should run (default to 300 seconds). CN_WAIT_SLEEP_DURATION : Delay between startup \"health checks\" (default to 10 seconds). GOOGLE_PROJECT_ID : Google Project ID (default to empty string). Used when CN_CONFIG_ADAPTER or CN_SECRET_ADAPTER set to google . GOOGLE_APPLICATION_CREDENTIALS : Optional JSON file (contains Google credentials) that can be injected into container for authentication. Refer to https://cloud.google.com/docs/authentication/provide-credentials-adc#how-to for supported credentials. CN_GOOGLE_SECRET_VERSION_ID : Janssen secret version ID in Google Secret Manager. Defaults to latest , which is recommended. CN_GOOGLE_SECRET_NAME_PREFIX : Prefix for Janssen secret in Google Secret Manager. Defaults to jans . If left jans-secret secret will be created. CN_GOOGLE_SECRET_MANAGER_PASSPHRASE : Passphrase for Janssen secret in Google Secret Manager. This is recommended to be changed and defaults to secret . CN_AUTH_BASE_URL : Base URL of auth server (default to empty). CN_CONFIG_API_BASE_URL : Base URL of config-api server (default to empty). CN_TOKEN_SERVER_BASE_URL : Base URL of token server (default to empty). CN_TOKEN_SERVER_AUTHZ_ENDPOINT : Authorization endpoint at token server (default to /jans-auth/authorize.htm ). CN_TOKEN_SERVER_TOKEN_ENDPOINT : Token endpoint at token server (default to /jans-auth/restv1/token ). CN_TOKEN_SERVER_INTROSPECTION_ENDPOINT : Introspection endpoint at token server (default to /jans-auth/restv1/introspection ). CN_TOKEN_SERVER_USERINFO_ENDPOINT : User info endpoint at token server (default to /jans-auth/restv1/userinfo ). CN_TOKEN_SERVER_CLIENT_ID : Client ID registered at token server. CN_TOKEN_SERVER_CERT_FILE : Path to token server certificate (default to /etc/certs/token_server.crt ). CN_PERSISTENCE_TYPE : Persistence backend being used (one of sql , spanner , couchbase , or hybrid ; default to sql ). CN_HYBRID_MAPPING : Specify data mapping for each persistence (default to \"{}\" ). Note this environment only takes effect when CN_PERSISTENCE_TYPE is set to hybrid . See hybrid mapping section for details. CN_COUCHBASE_URL : Address of Couchbase server (default to localhost ). CN_COUCHBASE_USER : Username of Couchbase server (default to admin ). CN_COUCHBASE_CERT_FILE : Couchbase root certificate location (default to /etc/certs/couchbase.crt ). CN_COUCHBASE_PASSWORD_FILE : Path to file contains Couchbase password (default to /etc/jans/conf/couchbase_password ). CN_COUCHBASE_CONN_TIMEOUT : Connect timeout used when a bucket is opened (default to 10000 milliseconds). CN_COUCHBASE_CONN_MAX_WAIT : Maximum time to wait before retrying connection (default to 20000 milliseconds). CN_COUCHBASE_SCAN_CONSISTENCY : Default scan consistency; one of not_bounded , request_plus , or statement_plus (default to not_bounded ). CN_COUCHBASE_BUCKET_PREFIX : Prefix for Couchbase buckets (default to jans ). CN_COUCHBASE_TRUSTSTORE_ENABLE : Enable truststore for encrypted Couchbase connection (default to true ). CN_COUCHBASE_KEEPALIVE_INTERVAL : Keep-alive interval for Couchbase connection (default to 30000 milliseconds). CN_COUCHBASE_KEEPALIVE_TIMEOUT : Keep-alive timeout for Couchbase connection (default to 2500 milliseconds). CN_SQL_DB_DIALECT : Dialect name of SQL backend (one of mysql , pgsql ; default to mysql ). CN_SQL_DB_HOST : Host of SQL backend (default to localhost ). CN_SQL_DB_PORT : Port of SQL backend (default to 3306 ). CN_SQL_DB_NAME : Database name (default to jans ) CN_SQL_DB_USER : Username to interact with SQL backend (default to jans ). CN_GOOGLE_SPANNER_INSTANCE_ID : Instance ID of Google Spanner (default to empty string). CN_GOOGLE_SPANNER_DATABASE_ID : Database ID of Google Spanner (default to empty string). GOOGLE_PROJECT_ID : Google Project ID (default to empty string). GOOGLE_PROJECT_ID : Google Project ID (default to empty string). Used when CN_CONFIG_ADAPTER or CN_SECRET_ADAPTER set to google . CN_GOOGLE_SPANNER_INSTANCE_ID : Google Spanner instance ID. CN_GOOGLE_SPANNER_DATABASE_ID : Google Spanner database ID. GLUU_ADMIN_UI_AUTH_METHOD : Authentication method for admin-ui (default to basic ). Note, changing the value require restart to jans-config-api. Hybrid mapping # Hybrid persistence supports all available persistence types. To configure hybrid persistence and its data mapping, follow steps below: Set CN_PERSISTENCE_TYPE environment variable to hybrid Set CN_HYBRID_MAPPING with the following format: { \"default\": \"\", \"user\": \"\", \"site\": \"\", \"cache\": \"\", \"token\": \"\", \"session\": \"\", } Example: { \"default\": \"sql\", \"user\": \"spanner\", \"site\": \"sql\", \"cache\": \"sql\", \"token\": \"couchbase\", \"session\": \"spanner\", }","title":"Admin UI Docker Image"},{"location":"reference/kubernetes/docker-admin-ui/#docker-admin-ui","text":"A containerized application for Gluu Admin UI frontend.","title":"docker-admin-ui"},{"location":"reference/kubernetes/docker-admin-ui/#versions","text":"See Releases for stable versions. For bleeding-edge/unstable version, use gluufederation/admin-ui:1.0.0_dev .","title":"Versions"},{"location":"reference/kubernetes/docker-admin-ui/#environment-variables","text":"The following environment variables are supported by the container: CN_CONFIG_ADAPTER : The config backend adapter, can be consul (default), kubernetes , or google . CN_CONFIG_CONSUL_HOST : hostname or IP of Consul (default to localhost ). CN_CONFIG_CONSUL_PORT : port of Consul (default to 8500 ). CN_CONFIG_CONSUL_CONSISTENCY : Consul consistency mode (choose one of default , consistent , or stale ). Default to stale mode. CN_CONFIG_CONSUL_SCHEME : supported Consul scheme ( http or https ). CN_CONFIG_CONSUL_VERIFY : whether to verify cert or not (default to false ). CN_CONFIG_CONSUL_CACERT_FILE : path to Consul CA cert file (default to /etc/certs/consul_ca.crt ). This file will be used if it exists and CN_CONFIG_CONSUL_VERIFY set to true . CN_CONFIG_CONSUL_CERT_FILE : path to Consul cert file (default to /etc/certs/consul_client.crt ). CN_CONFIG_CONSUL_KEY_FILE : path to Consul key file (default to /etc/certs/consul_client.key ). CN_CONFIG_CONSUL_TOKEN_FILE : path to file contains ACL token (default to /etc/certs/consul_token ). CN_CONFIG_KUBERNETES_NAMESPACE : Kubernetes namespace (default to default ). CN_CONFIG_KUBERNETES_CONFIGMAP : Kubernetes configmaps name (default to jans ). CN_CONFIG_KUBERNETES_USE_KUBE_CONFIG : Load credentials from $HOME/.kube/config , only useful for non-container environment (default to false ). CN_SECRET_ADAPTER : The secrets' adapter, can be vault (default), kubernetes , or google . CN_SECRET_VAULT_VERIFY : whether to verify cert or not (default to false ). CN_SECRET_VAULT_ROLE_ID_FILE : path to file contains Vault AppRole role ID (default to /etc/certs/vault_role_id ). CN_SECRET_VAULT_SECRET_ID_FILE : path to file contains Vault AppRole secret ID (default to /etc/certs/vault_secret_id ). CN_SECRET_VAULT_CERT_FILE : path to Vault cert file (default to /etc/certs/vault_client.crt ). CN_SECRET_VAULT_KEY_FILE : path to Vault key file (default to /etc/certs/vault_client.key ). CN_SECRET_VAULT_CACERT_FILE : path to Vault CA cert file (default to /etc/certs/vault_ca.crt ). This file will be used if it exists and CN_SECRET_VAULT_VERIFY set to true . CN_SECRET_VAULT_ADDR : URL of Vault (default to http://localhost:8200 ). CN_SECRET_VAULT_NAMESPACE : Namespace used to access secrets (default to empty string). CN_SECRET_VAULT_KV_PATH : Path to KV secrets engine (default to secret ). CN_SECRET_VAULT_PREFIX : Base prefix name used to build secret path (default to jans ). CN_SECRET_VAULT_APPROLE_PATH : Path to AppRole (default to approle ). CN_SECRET_KUBERNETES_NAMESPACE : Kubernetes namespace (default to default ). CN_SECRET_KUBERNETES_CONFIGMAP : Kubernetes secrets name (default to jans ). CN_SECRET_KUBERNETES_USE_KUBE_CONFIG : Load credentials from $HOME/.kube/config , only useful for non-container environment (default to false ). CN_WAIT_MAX_TIME : How long the startup \"health checks\" should run (default to 300 seconds). CN_WAIT_SLEEP_DURATION : Delay between startup \"health checks\" (default to 10 seconds). GOOGLE_PROJECT_ID : Google Project ID (default to empty string). Used when CN_CONFIG_ADAPTER or CN_SECRET_ADAPTER set to google . GOOGLE_APPLICATION_CREDENTIALS : Optional JSON file (contains Google credentials) that can be injected into container for authentication. Refer to https://cloud.google.com/docs/authentication/provide-credentials-adc#how-to for supported credentials. CN_GOOGLE_SECRET_VERSION_ID : Janssen secret version ID in Google Secret Manager. Defaults to latest , which is recommended. CN_GOOGLE_SECRET_NAME_PREFIX : Prefix for Janssen secret in Google Secret Manager. Defaults to jans . If left jans-secret secret will be created. CN_GOOGLE_SECRET_MANAGER_PASSPHRASE : Passphrase for Janssen secret in Google Secret Manager. This is recommended to be changed and defaults to secret . CN_AUTH_BASE_URL : Base URL of auth server (default to empty). CN_CONFIG_API_BASE_URL : Base URL of config-api server (default to empty). CN_TOKEN_SERVER_BASE_URL : Base URL of token server (default to empty). CN_TOKEN_SERVER_AUTHZ_ENDPOINT : Authorization endpoint at token server (default to /jans-auth/authorize.htm ). CN_TOKEN_SERVER_TOKEN_ENDPOINT : Token endpoint at token server (default to /jans-auth/restv1/token ). CN_TOKEN_SERVER_INTROSPECTION_ENDPOINT : Introspection endpoint at token server (default to /jans-auth/restv1/introspection ). CN_TOKEN_SERVER_USERINFO_ENDPOINT : User info endpoint at token server (default to /jans-auth/restv1/userinfo ). CN_TOKEN_SERVER_CLIENT_ID : Client ID registered at token server. CN_TOKEN_SERVER_CERT_FILE : Path to token server certificate (default to /etc/certs/token_server.crt ). CN_PERSISTENCE_TYPE : Persistence backend being used (one of sql , spanner , couchbase , or hybrid ; default to sql ). CN_HYBRID_MAPPING : Specify data mapping for each persistence (default to \"{}\" ). Note this environment only takes effect when CN_PERSISTENCE_TYPE is set to hybrid . See hybrid mapping section for details. CN_COUCHBASE_URL : Address of Couchbase server (default to localhost ). CN_COUCHBASE_USER : Username of Couchbase server (default to admin ). CN_COUCHBASE_CERT_FILE : Couchbase root certificate location (default to /etc/certs/couchbase.crt ). CN_COUCHBASE_PASSWORD_FILE : Path to file contains Couchbase password (default to /etc/jans/conf/couchbase_password ). CN_COUCHBASE_CONN_TIMEOUT : Connect timeout used when a bucket is opened (default to 10000 milliseconds). CN_COUCHBASE_CONN_MAX_WAIT : Maximum time to wait before retrying connection (default to 20000 milliseconds). CN_COUCHBASE_SCAN_CONSISTENCY : Default scan consistency; one of not_bounded , request_plus , or statement_plus (default to not_bounded ). CN_COUCHBASE_BUCKET_PREFIX : Prefix for Couchbase buckets (default to jans ). CN_COUCHBASE_TRUSTSTORE_ENABLE : Enable truststore for encrypted Couchbase connection (default to true ). CN_COUCHBASE_KEEPALIVE_INTERVAL : Keep-alive interval for Couchbase connection (default to 30000 milliseconds). CN_COUCHBASE_KEEPALIVE_TIMEOUT : Keep-alive timeout for Couchbase connection (default to 2500 milliseconds). CN_SQL_DB_DIALECT : Dialect name of SQL backend (one of mysql , pgsql ; default to mysql ). CN_SQL_DB_HOST : Host of SQL backend (default to localhost ). CN_SQL_DB_PORT : Port of SQL backend (default to 3306 ). CN_SQL_DB_NAME : Database name (default to jans ) CN_SQL_DB_USER : Username to interact with SQL backend (default to jans ). CN_GOOGLE_SPANNER_INSTANCE_ID : Instance ID of Google Spanner (default to empty string). CN_GOOGLE_SPANNER_DATABASE_ID : Database ID of Google Spanner (default to empty string). GOOGLE_PROJECT_ID : Google Project ID (default to empty string). GOOGLE_PROJECT_ID : Google Project ID (default to empty string). Used when CN_CONFIG_ADAPTER or CN_SECRET_ADAPTER set to google . CN_GOOGLE_SPANNER_INSTANCE_ID : Google Spanner instance ID. CN_GOOGLE_SPANNER_DATABASE_ID : Google Spanner database ID. GLUU_ADMIN_UI_AUTH_METHOD : Authentication method for admin-ui (default to basic ). Note, changing the value require restart to jans-config-api.","title":"Environment Variables"},{"location":"reference/kubernetes/docker-admin-ui/#hybrid-mapping","text":"Hybrid persistence supports all available persistence types. To configure hybrid persistence and its data mapping, follow steps below: Set CN_PERSISTENCE_TYPE environment variable to hybrid Set CN_HYBRID_MAPPING with the following format: { \"default\": \"\", \"user\": \"\", \"site\": \"\", \"cache\": \"\", \"token\": \"\", \"session\": \"\", } Example: { \"default\": \"sql\", \"user\": \"spanner\", \"site\": \"sql\", \"cache\": \"sql\", \"token\": \"couchbase\", \"session\": \"spanner\", }","title":"Hybrid mapping"},{"location":"reference/kubernetes/docker-flex-monolith/","tags":["administration","reference","kubernetes","docker image","docker compose"],"text":"Warning This image is for testing and development purposes only. Use Flex helm charts for production setups. Overview # Docker monolith image packaging for Gluu Flex. This image packs janssen services including the auth-server, config-api, fido2, casa, scim and the Gluu admin ui. Pre-requisites # Docker Docker compose Versions # See Releases for stable versions. This image should never be used in production. For bleeding-edge/unstable version, use gluufederation/monolith:5.0.0_dev . Environment Variables # Installation depends on the set of environment variables shown below. These environment variables can be set to customize installation as per the need. If not set, the installer uses default values. ENV Description Default CN_HOSTNAME Hostname to install gluu with. demoexample.gluu.org CN_ADMIN_PASS Password of the admin user. 1t5Fin3#security CN_ORG_NAME Organization name. Used for ssl cert generation. Gluu CN_EMAIL Email. Used for ssl cert generation. team@gluu.org CN_CITY City. Used for ssl cert generation. Austin CN_STATE State. Used for ssl cert generation TX CN_COUNTRY Country. Used for ssl cert generation. US CN_INSTALL_MYSQL Install gluu with mysql as the backend false CN_INSTALL_PGSQL Install gluu with Postgres as the backend false CN_INSTALL_ADMIN_UI Installs the Admin-UI true CN_INSTALL_CONFIG_API Installs the Config API service. true CN_INSTALL_SCIM Installs the SCIM API service. true CN_INSTALL_FIDO2 Installs the FIDO2 API service. true RDBMS_DATABASE RDBMS gluu database for MySQL or Postgres. gluu RDBMS_USER RDBMS database user for MySQL or Postgres. gluu RDBMS_PASSWORD RDBMS database user password for MySQL or Postgres. 1t5Fin3#security RDBMS_HOST RDBMS host for MySQL or Postgres. mysql which is the docker compose service name TEST_CLIENT_ID ID of test client in UUID which has all available scopes to access any gluu API 9876baac-de39-4c23-8a78-674b59df8c09 TEST_CLIENT_SECRET Secret for test client 1t5Fin3#security TEST_CLIENT_TRUSTED Trust test client true TEST_CLIENT_REDIRECT_URI Not Implemented yet Redirect URI for test client. Multiple uri's with comma may be provided, if not provided redirect uris will be same as the config-api-client `` How to run # Download the compose file of your chosen persistence from mysql or postgres wget https://raw.githubusercontent.com/GluuFederation/flex/main/docker-flex-monolith/flex-mysql-compose.yml wget https://raw.githubusercontent.com/GluuFederation/flex/main/docker-flex-monolith/flex-postgres-compose.yml Download the script files wget https://raw.githubusercontent.com/GluuFederation/flex/main/docker-flex-monolith/up.sh wget https://raw.githubusercontent.com/GluuFederation/flex/main/docker-flex-monolith/down.sh wget https://raw.githubusercontent.com/GluuFederation/flex/main/docker-flex-monolith/clean.sh Give execute permission to the scripts chmod u+x up.sh down.sh clean.sh This docker compose file runs two containers, the flex monolith container and mysql container. To start the containers. ./up.sh #You can pass mysql|postgres as an argument to the script. If you don't pass any, it will default to mysql. To view the containers running docker compose -f flex-mysql-compose.yml ps To stop the containers. ./down.sh #You can pass mysql|postgres as an argument to the script. If you don't pass any, it will default to mysql. Configure Gluu flex # Access the Docker container shell using: docker compose -f flex-mysql-compose.yml exec flex /bin/bash #This opens a bash terminal in the running container You can grab client_id and client_pw (secret), and other values from setup.properties or /opt/jans/jans-setup/setup.properties.last Use the CLI tools located under /opt/jans/jans-cli/ to configure Gluu flex as needed. For example you can run the TUI : python3 /opt/jans/jans-cli/config-cli-tui.py Access endpoints externally # Add to your /etc/hosts file the ip domain record which should be the ip of the instance docker is installed at and the domain used in the env above CN_HOSTNAME . # For-example 172 .22.0.3 demoexample.gluu.org After adding the record you can hit endpoints such as https://demoexample.gluu.org/.well-known/openid-configuration Clean up # Remove setup and volumes ./clean.sh #You can pass mysql|postgres as an argument to the script. If you don't pass any, it will default to mysql.","title":"Flex Monolith Docker Image"},{"location":"reference/kubernetes/docker-flex-monolith/#overview","text":"Docker monolith image packaging for Gluu Flex. This image packs janssen services including the auth-server, config-api, fido2, casa, scim and the Gluu admin ui.","title":"Overview"},{"location":"reference/kubernetes/docker-flex-monolith/#pre-requisites","text":"Docker Docker compose","title":"Pre-requisites"},{"location":"reference/kubernetes/docker-flex-monolith/#versions","text":"See Releases for stable versions. This image should never be used in production. For bleeding-edge/unstable version, use gluufederation/monolith:5.0.0_dev .","title":"Versions"},{"location":"reference/kubernetes/docker-flex-monolith/#environment-variables","text":"Installation depends on the set of environment variables shown below. These environment variables can be set to customize installation as per the need. If not set, the installer uses default values. ENV Description Default CN_HOSTNAME Hostname to install gluu with. demoexample.gluu.org CN_ADMIN_PASS Password of the admin user. 1t5Fin3#security CN_ORG_NAME Organization name. Used for ssl cert generation. Gluu CN_EMAIL Email. Used for ssl cert generation. team@gluu.org CN_CITY City. Used for ssl cert generation. Austin CN_STATE State. Used for ssl cert generation TX CN_COUNTRY Country. Used for ssl cert generation. US CN_INSTALL_MYSQL Install gluu with mysql as the backend false CN_INSTALL_PGSQL Install gluu with Postgres as the backend false CN_INSTALL_ADMIN_UI Installs the Admin-UI true CN_INSTALL_CONFIG_API Installs the Config API service. true CN_INSTALL_SCIM Installs the SCIM API service. true CN_INSTALL_FIDO2 Installs the FIDO2 API service. true RDBMS_DATABASE RDBMS gluu database for MySQL or Postgres. gluu RDBMS_USER RDBMS database user for MySQL or Postgres. gluu RDBMS_PASSWORD RDBMS database user password for MySQL or Postgres. 1t5Fin3#security RDBMS_HOST RDBMS host for MySQL or Postgres. mysql which is the docker compose service name TEST_CLIENT_ID ID of test client in UUID which has all available scopes to access any gluu API 9876baac-de39-4c23-8a78-674b59df8c09 TEST_CLIENT_SECRET Secret for test client 1t5Fin3#security TEST_CLIENT_TRUSTED Trust test client true TEST_CLIENT_REDIRECT_URI Not Implemented yet Redirect URI for test client. Multiple uri's with comma may be provided, if not provided redirect uris will be same as the config-api-client ``","title":"Environment Variables"},{"location":"reference/kubernetes/docker-flex-monolith/#how-to-run","text":"Download the compose file of your chosen persistence from mysql or postgres wget https://raw.githubusercontent.com/GluuFederation/flex/main/docker-flex-monolith/flex-mysql-compose.yml wget https://raw.githubusercontent.com/GluuFederation/flex/main/docker-flex-monolith/flex-postgres-compose.yml Download the script files wget https://raw.githubusercontent.com/GluuFederation/flex/main/docker-flex-monolith/up.sh wget https://raw.githubusercontent.com/GluuFederation/flex/main/docker-flex-monolith/down.sh wget https://raw.githubusercontent.com/GluuFederation/flex/main/docker-flex-monolith/clean.sh Give execute permission to the scripts chmod u+x up.sh down.sh clean.sh This docker compose file runs two containers, the flex monolith container and mysql container. To start the containers. ./up.sh #You can pass mysql|postgres as an argument to the script. If you don't pass any, it will default to mysql. To view the containers running docker compose -f flex-mysql-compose.yml ps To stop the containers. ./down.sh #You can pass mysql|postgres as an argument to the script. If you don't pass any, it will default to mysql.","title":"How to run"},{"location":"reference/kubernetes/docker-flex-monolith/#configure-gluu-flex","text":"Access the Docker container shell using: docker compose -f flex-mysql-compose.yml exec flex /bin/bash #This opens a bash terminal in the running container You can grab client_id and client_pw (secret), and other values from setup.properties or /opt/jans/jans-setup/setup.properties.last Use the CLI tools located under /opt/jans/jans-cli/ to configure Gluu flex as needed. For example you can run the TUI : python3 /opt/jans/jans-cli/config-cli-tui.py","title":"Configure Gluu flex"},{"location":"reference/kubernetes/docker-flex-monolith/#access-endpoints-externally","text":"Add to your /etc/hosts file the ip domain record which should be the ip of the instance docker is installed at and the domain used in the env above CN_HOSTNAME . # For-example 172 .22.0.3 demoexample.gluu.org After adding the record you can hit endpoints such as https://demoexample.gluu.org/.well-known/openid-configuration","title":"Access endpoints externally"},{"location":"reference/kubernetes/docker-flex-monolith/#clean-up","text":"Remove setup and volumes ./clean.sh #You can pass mysql|postgres as an argument to the script. If you don't pass any, it will default to mysql.","title":"Clean up"},{"location":"reference/kubernetes/helm-chart/","text":"gluu # Gluu Access and Identity Management Homepage: https://www.gluu.org Maintainers # Name Email Url moabu team@gluu.org Source Code # https://docs.gluu.org Requirements # Kubernetes: >=v1.21.0-0 Repository Name Version admin-ui 5.1.4 auth-server 1.1.4 auth-server-key-rotation 1.1.4 casa 1.1.4 cn-istio-ingress 5.1.4 config 1.1.4 config-api 1.1.4 fido2 1.1.4 kc-scheduler 1.1.4 link 1.1.4 nginx-ingress 5.1.4 persistence 1.1.4 saml 1.1.4 scim 1.1.4 Values # Key Type Default Description admin-ui object {\"additionalAnnotations\":{},\"additionalLabels\":{},\"customScripts\":[],\"dnsConfig\":{},\"dnsPolicy\":\"\",\"hpa\":{\"behavior\":{},\"enabled\":true,\"maxReplicas\":10,\"metrics\":[],\"minReplicas\":1,\"targetCPUUtilizationPercentage\":50},\"image\":{\"pullPolicy\":\"IfNotPresent\",\"pullSecrets\":[],\"repository\":\"ghcr.io/gluufederation/flex/admin-ui\",\"tag\":\"5.1.3-1\"},\"lifecycle\":{},\"livenessProbe\":{\"failureThreshold\":20,\"initialDelaySeconds\":60,\"periodSeconds\":25,\"tcpSocket\":{\"port\":8080},\"timeoutSeconds\":5},\"pdb\":{\"enabled\":true,\"maxUnavailable\":\"90%\"},\"readinessProbe\":{\"failureThreshold\":20,\"initialDelaySeconds\":60,\"periodSeconds\":25,\"tcpSocket\":{\"port\":8080},\"timeoutSeconds\":5},\"replicas\":1,\"resources\":{\"limits\":{\"cpu\":\"2000m\",\"memory\":\"2000Mi\"},\"requests\":{\"cpu\":\"2000m\",\"memory\":\"2000Mi\"}},\"topologySpreadConstraints\":{},\"usrEnvs\":{\"normal\":{},\"secret\":{}},\"volumeMounts\":[],\"volumes\":[]} Admin GUI for configuration of the auth-server admin-ui.additionalAnnotations object {} Additional annotations that will be added across the gateway in the format of admin-ui.additionalLabels object {} Additional labels that will be added across the gateway in the format of admin-ui.customScripts list [] Add custom scripts that have been mounted to run before the entrypoint. - /tmp/custom.sh - /tmp/custom2.sh admin-ui.dnsConfig object {} Add custom dns config admin-ui.dnsPolicy string \"\" Add custom dns policy admin-ui.hpa object {\"behavior\":{},\"enabled\":true,\"maxReplicas\":10,\"metrics\":[],\"minReplicas\":1,\"targetCPUUtilizationPercentage\":50} Configure the HorizontalPodAutoscaler admin-ui.hpa.behavior object {} Scaling Policies admin-ui.hpa.metrics list [] metrics if targetCPUUtilizationPercentage is not set admin-ui.image.pullPolicy string \"IfNotPresent\" Image pullPolicy to use for deploying. admin-ui.image.pullSecrets list [] Image Pull Secrets admin-ui.image.repository string \"ghcr.io/gluufederation/flex/admin-ui\" Image to use for deploying. admin-ui.image.tag string \"5.1.3-1\" Image tag to use for deploying. admin-ui.livenessProbe object {\"failureThreshold\":20,\"initialDelaySeconds\":60,\"periodSeconds\":25,\"tcpSocket\":{\"port\":8080},\"timeoutSeconds\":5} Configure the liveness healthcheck for the admin ui if needed. admin-ui.pdb object {\"enabled\":true,\"maxUnavailable\":\"90%\"} Configure the PodDisruptionBudget admin-ui.readinessProbe object {\"failureThreshold\":20,\"initialDelaySeconds\":60,\"periodSeconds\":25,\"tcpSocket\":{\"port\":8080},\"timeoutSeconds\":5} Configure the readiness healthcheck for the admin ui if needed. admin-ui.replicas int 1 Service replica number. admin-ui.resources object {\"limits\":{\"cpu\":\"2000m\",\"memory\":\"2000Mi\"},\"requests\":{\"cpu\":\"2000m\",\"memory\":\"2000Mi\"}} Resource specs. admin-ui.resources.limits.cpu string \"2000m\" CPU limit. admin-ui.resources.limits.memory string \"2000Mi\" Memory limit. admin-ui.resources.requests.cpu string \"2000m\" CPU request. admin-ui.resources.requests.memory string \"2000Mi\" Memory request. admin-ui.topologySpreadConstraints object {} Configure the topology spread constraints. Notice this is a map NOT a list as in the upstream API https://kubernetes.io/docs/concepts/scheduling-eviction/topology-spread-constraints/ admin-ui.usrEnvs object {\"normal\":{},\"secret\":{}} Add custom normal and secret envs to the service admin-ui.usrEnvs.normal object {} Add custom normal envs to the service variable1: value1 admin-ui.usrEnvs.secret object {} Add custom secret envs to the service variable1: value1 admin-ui.volumeMounts list [] Configure any additional volumesMounts that need to be attached to the containers admin-ui.volumes list [] Configure any additional volumes that need to be attached to the pod auth-server object {\"additionalAnnotations\":{},\"additionalLabels\":{},\"customScripts\":[],\"dnsConfig\":{},\"dnsPolicy\":\"\",\"hpa\":{\"behavior\":{},\"enabled\":true,\"maxReplicas\":10,\"metrics\":[],\"minReplicas\":1,\"targetCPUUtilizationPercentage\":50},\"image\":{\"pullPolicy\":\"IfNotPresent\",\"pullSecrets\":[],\"repository\":\"ghcr.io/janssenproject/jans/auth-server\",\"tag\":\"1.1.6_dev\"},\"lifecycle\":{},\"livenessProbe\":{\"exec\":{\"command\":[\"python3\",\"/app/scripts/healthcheck.py\"]},\"initialDelaySeconds\":30,\"periodSeconds\":30,\"timeoutSeconds\":5},\"pdb\":{\"enabled\":true,\"maxUnavailable\":\"90%\"},\"readinessProbe\":{\"exec\":{\"command\":[\"python3\",\"/app/scripts/healthcheck.py\"]},\"initialDelaySeconds\":25,\"periodSeconds\":25,\"timeoutSeconds\":5},\"replicas\":1,\"resources\":{\"limits\":{\"cpu\":\"2500m\",\"memory\":\"2500Mi\"},\"requests\":{\"cpu\":\"2500m\",\"memory\":\"2500Mi\"}},\"topologySpreadConstraints\":{},\"usrEnvs\":{\"normal\":{},\"secret\":{}},\"volumeMounts\":[],\"volumes\":[]} OAuth Authorization Server, the OpenID Connect Provider, the UMA Authorization Server--this is the main Internet facing component of Gluu. It's the service that returns tokens, JWT's and identity assertions. This service must be Internet facing. auth-server-key-rotation object {\"additionalAnnotations\":{},\"additionalLabels\":{},\"customScripts\":[],\"dnsConfig\":{},\"dnsPolicy\":\"\",\"image\":{\"pullPolicy\":\"IfNotPresent\",\"pullSecrets\":[],\"repository\":\"ghcr.io/janssenproject/jans/certmanager\",\"tag\":\"1.1.6_dev\"},\"keysLife\":48,\"keysPushDelay\":0,\"keysPushStrategy\":\"NEWER\",\"keysStrategy\":\"NEWER\",\"lifecycle\":{},\"resources\":{\"limits\":{\"cpu\":\"300m\",\"memory\":\"300Mi\"},\"requests\":{\"cpu\":\"300m\",\"memory\":\"300Mi\"}},\"usrEnvs\":{\"normal\":{},\"secret\":{}},\"volumeMounts\":[],\"volumes\":[]} Responsible for regenerating auth-keys per x hours auth-server-key-rotation.additionalAnnotations object {} Additional annotations that will be added across the gateway in the format of auth-server-key-rotation.additionalLabels object {} Additional labels that will be added across the gateway in the format of auth-server-key-rotation.customScripts list [] Add custom scripts that have been mounted to run before the entrypoint. - /tmp/custom.sh - /tmp/custom2.sh auth-server-key-rotation.dnsConfig object {} Add custom dns config auth-server-key-rotation.dnsPolicy string \"\" Add custom dns policy auth-server-key-rotation.image.pullPolicy string \"IfNotPresent\" Image pullPolicy to use for deploying. auth-server-key-rotation.image.pullSecrets list [] Image Pull Secrets auth-server-key-rotation.image.repository string \"ghcr.io/janssenproject/jans/certmanager\" Image to use for deploying. auth-server-key-rotation.image.tag string \"1.1.3-1\" Image tag to use for deploying. auth-server-key-rotation.keysLife int 48 Auth server key rotation keys life in hours auth-server-key-rotation.keysPushDelay int 0 Delay (in seconds) before pushing private keys to Auth server auth-server-key-rotation.keysPushStrategy string \"NEWER\" Set key selection strategy after pushing private keys to Auth server (only takes effect when keysPushDelay value is greater than 0) auth-server-key-rotation.keysStrategy string \"NEWER\" Set key selection strategy used by Auth server auth-server-key-rotation.resources object {\"limits\":{\"cpu\":\"300m\",\"memory\":\"300Mi\"},\"requests\":{\"cpu\":\"300m\",\"memory\":\"300Mi\"}} Resource specs. auth-server-key-rotation.resources.limits.cpu string \"300m\" CPU limit. auth-server-key-rotation.resources.limits.memory string \"300Mi\" Memory limit. auth-server-key-rotation.resources.requests.cpu string \"300m\" CPU request. auth-server-key-rotation.resources.requests.memory string \"300Mi\" Memory request. auth-server-key-rotation.usrEnvs object {\"normal\":{},\"secret\":{}} Add custom normal and secret envs to the service auth-server-key-rotation.usrEnvs.normal object {} Add custom normal envs to the service variable1: value1 auth-server-key-rotation.usrEnvs.secret object {} Add custom secret envs to the service variable1: value1 auth-server-key-rotation.volumeMounts list [] Configure any additional volumesMounts that need to be attached to the containers auth-server-key-rotation.volumes list [] Configure any additional volumes that need to be attached to the pod auth-server.additionalAnnotations object {} Additional annotations that will be added across the gateway in the format of auth-server.additionalLabels object {} Additional labels that will be added across the gateway in the format of auth-server.customScripts list [] Add custom scripts that have been mounted to run before the entrypoint. - /tmp/custom.sh - /tmp/custom2.sh auth-server.dnsConfig object {} Add custom dns config auth-server.dnsPolicy string \"\" Add custom dns policy auth-server.hpa object {\"behavior\":{},\"enabled\":true,\"maxReplicas\":10,\"metrics\":[],\"minReplicas\":1,\"targetCPUUtilizationPercentage\":50} Configure the HorizontalPodAutoscaler auth-server.hpa.behavior object {} Scaling Policies auth-server.hpa.metrics list [] metrics if targetCPUUtilizationPercentage is not set auth-server.image.pullPolicy string \"IfNotPresent\" Image pullPolicy to use for deploying. auth-server.image.pullSecrets list [] Image Pull Secrets auth-server.image.repository string \"ghcr.io/janssenproject/jans/auth-server\" Image to use for deploying. auth-server.image.tag string \"1.1.6_dev\" Image tag to use for deploying. auth-server.livenessProbe object {\"exec\":{\"command\":[\"python3\",\"/app/scripts/healthcheck.py\"]},\"initialDelaySeconds\":30,\"periodSeconds\":30,\"timeoutSeconds\":5} Configure the liveness healthcheck for the auth server if needed. auth-server.livenessProbe.exec object {\"command\":[\"python3\",\"/app/scripts/healthcheck.py\"]} Executes the python3 healthcheck. https://github.com/JanssenProject/docker-jans-auth-server/blob/master/scripts/healthcheck.py auth-server.pdb object {\"enabled\":true,\"maxUnavailable\":\"90%\"} Configure the PodDisruptionBudget auth-server.readinessProbe object {\"exec\":{\"command\":[\"python3\",\"/app/scripts/healthcheck.py\"]},\"initialDelaySeconds\":25,\"periodSeconds\":25,\"timeoutSeconds\":5} Configure the readiness healthcheck for the auth server if needed. https://github.com/JanssenProject/docker-jans-auth-server/blob/master/scripts/healthcheck.py auth-server.replicas int 1 Service replica number. auth-server.resources object {\"limits\":{\"cpu\":\"2500m\",\"memory\":\"2500Mi\"},\"requests\":{\"cpu\":\"2500m\",\"memory\":\"2500Mi\"}} Resource specs. auth-server.resources.limits.cpu string \"2500m\" CPU limit. auth-server.resources.limits.memory string \"2500Mi\" Memory limit. This value is used to calculate memory allocation for Java. Currently it only supports Mi . Please refrain from using other units. auth-server.resources.requests.cpu string \"2500m\" CPU request. auth-server.resources.requests.memory string \"2500Mi\" Memory request. auth-server.topologySpreadConstraints object {} Configure the topology spread constraints. Notice this is a map NOT a list as in the upstream API https://kubernetes.io/docs/concepts/scheduling-eviction/topology-spread-constraints/ auth-server.usrEnvs object {\"normal\":{},\"secret\":{}} Add custom normal and secret envs to the service auth-server.usrEnvs.normal object {} Add custom normal envs to the service variable1: value1 auth-server.usrEnvs.secret object {} Add custom secret envs to the service variable1: value1 auth-server.volumeMounts list [] Configure any additional volumesMounts that need to be attached to the containers auth-server.volumes list [] Configure any additional volumes that need to be attached to the pod casa object {\"additionalAnnotations\":{},\"additionalLabels\":{},\"customScripts\":[],\"dnsConfig\":{},\"dnsPolicy\":\"\",\"hpa\":{\"behavior\":{},\"enabled\":true,\"maxReplicas\":10,\"metrics\":[],\"minReplicas\":1,\"targetCPUUtilizationPercentage\":50},\"image\":{\"pullPolicy\":\"IfNotPresent\",\"pullSecrets\":[],\"repository\":\"ghcr.io/janssenproject/jans/casa\",\"tag\":\"1.1.6_dev\"},\"lifecycle\":{},\"livenessProbe\":{\"httpGet\":{\"path\":\"/jans-casa/health-check\",\"port\":\"http-casa\"},\"initialDelaySeconds\":25,\"periodSeconds\":25,\"timeoutSeconds\":5},\"pdb\":{\"enabled\":true,\"maxUnavailable\":\"90%\"},\"readinessProbe\":{\"httpGet\":{\"path\":\"/jans-casa/health-check\",\"port\":\"http-casa\"},\"initialDelaySeconds\":30,\"periodSeconds\":30,\"timeoutSeconds\":5},\"replicas\":1,\"resources\":{\"limits\":{\"cpu\":\"500m\",\"memory\":\"500Mi\"},\"requests\":{\"cpu\":\"500m\",\"memory\":\"500Mi\"}},\"topologySpreadConstraints\":{},\"usrEnvs\":{\"normal\":{},\"secret\":{}},\"volumeMounts\":[],\"volumes\":[]} Janssen Casa (\"Casa\") is a self-service web portal for end-users to manage authentication and authorization preferences for their account in a Janssen Auth Server. casa.additionalAnnotations object {} Additional annotations that will be added across the gateway in the format of casa.additionalLabels object {} Additional labels that will be added across the gateway in the format of casa.customScripts list [] Add custom scripts that have been mounted to run before the entrypoint. - /tmp/custom.sh - /tmp/custom2.sh casa.dnsConfig object {} Add custom dns config casa.dnsPolicy string \"\" Add custom dns policy casa.hpa object {\"behavior\":{},\"enabled\":true,\"maxReplicas\":10,\"metrics\":[],\"minReplicas\":1,\"targetCPUUtilizationPercentage\":50} Configure the HorizontalPodAutoscaler casa.hpa.behavior object {} Scaling Policies casa.hpa.metrics list [] metrics if targetCPUUtilizationPercentage is not set casa.image.pullPolicy string \"IfNotPresent\" Image pullPolicy to use for deploying. casa.image.pullSecrets list [] Image Pull Secrets casa.image.repository string \"ghcr.io/janssenproject/jans/casa\" Image to use for deploying. casa.image.tag string \"1.1.6_dev\" Image tag to use for deploying. casa.livenessProbe object {\"httpGet\":{\"path\":\"/jans-casa/health-check\",\"port\":\"http-casa\"},\"initialDelaySeconds\":25,\"periodSeconds\":25,\"timeoutSeconds\":5} Configure the liveness healthcheck for casa if needed. casa.livenessProbe.httpGet.path string \"/jans-casa/health-check\" http liveness probe endpoint casa.pdb object {\"enabled\":true,\"maxUnavailable\":\"90%\"} Configure the PodDisruptionBudget casa.readinessProbe object {\"httpGet\":{\"path\":\"/jans-casa/health-check\",\"port\":\"http-casa\"},\"initialDelaySeconds\":30,\"periodSeconds\":30,\"timeoutSeconds\":5} Configure the readiness healthcheck for the casa if needed. casa.readinessProbe.httpGet.path string \"/jans-casa/health-check\" http readiness probe endpoint casa.replicas int 1 Service replica number. casa.resources object {\"limits\":{\"cpu\":\"500m\",\"memory\":\"500Mi\"},\"requests\":{\"cpu\":\"500m\",\"memory\":\"500Mi\"}} Resource specs. casa.resources.limits.cpu string \"500m\" CPU limit. casa.resources.limits.memory string \"500Mi\" Memory limit. This value is used to calculate memory allocation for Java. Currently it only supports Mi . Please refrain from using other units. casa.resources.requests.cpu string \"500m\" CPU request. casa.resources.requests.memory string \"500Mi\" Memory request. casa.topologySpreadConstraints object {} Configure the topology spread constraints. Notice this is a map NOT a list as in the upstream API https://kubernetes.io/docs/concepts/scheduling-eviction/topology-spread-constraints/ casa.usrEnvs object {\"normal\":{},\"secret\":{}} Add custom normal and secret envs to the service casa.usrEnvs.normal object {} Add custom normal envs to the service variable1: value1 casa.usrEnvs.secret object {} Add custom secret envs to the service variable1: value1 casa.volumeMounts list [] Configure any additional volumesMounts that need to be attached to the containers casa.volumes list [] Configure any additional volumes that need to be attached to the pod config object {\"additionalAnnotations\":{},\"additionalLabels\":{},\"adminPassword\":\"Test1234#\",\"city\":\"Austin\",\"configmap\":{\"cnAwsAccessKeyId\":\"\",\"cnAwsDefaultRegion\":\"us-west-1\",\"cnAwsProfile\":\"gluu\",\"cnAwsSecretAccessKey\":\"\",\"cnAwsSecretsEndpointUrl\":\"\",\"cnAwsSecretsNamePrefix\":\"gluu\",\"cnAwsSecretsReplicaRegions\":[],\"cnCacheType\":\"NATIVE_PERSISTENCE\",\"cnConfigKubernetesConfigMap\":\"cn\",\"cnCouchbaseBucketPrefix\":\"jans\",\"cnCouchbaseCrt\":\"SWFtTm90YVNlcnZpY2VBY2NvdW50Q2hhbmdlTWV0b09uZQo=\",\"cnCouchbaseIndexNumReplica\":0,\"cnCouchbasePassword\":\"P@ssw0rd\",\"cnCouchbaseSuperUser\":\"admin\",\"cnCouchbaseSuperUserPassword\":\"Test1234#\",\"cnCouchbaseUrl\":\"cbgluu.default.svc.cluster.local\",\"cnCouchbaseUser\":\"gluu\",\"cnGoogleProjectId\":\"google-project-to-save-config-and-secrets-to\",\"cnGoogleSecretManagerServiceAccount\":\"SWFtTm90YVNlcnZpY2VBY2NvdW50Q2hhbmdlTWV0b09uZQo=\",\"cnGoogleSecretNamePrefix\":\"gluu\",\"cnGoogleSecretVersionId\":\"latest\",\"cnGoogleSpannerDatabaseId\":\"\",\"cnGoogleSpannerInstanceId\":\"\",\"cnJettyRequestHeaderSize\":8192,\"cnLdapCrt\":\"SWFtTm90YVNlcnZpY2VBY2NvdW50Q2hhbmdlTWV0b09uZQo=\",\"cnLdapKey\":\"SWFtTm90YVNlcnZpY2VBY2NvdW50Q2hhbmdlTWV0b09uZQo=\",\"cnLdapUrl\":\"opendj:1636\",\"cnMaxRamPercent\":\"75.0\",\"cnMessageType\":\"DISABLED\",\"cnOpaUrl\":\"http://opa.opa.svc.cluster.cluster.local:8181/v1\",\"cnPersistenceHybridMapping\":\"{}\",\"cnRedisSentinelGroup\":\"\",\"cnRedisSslTruststore\":\"\",\"cnRedisType\":\"STANDALONE\",\"cnRedisUrl\":\"redis.redis.svc.cluster.local:6379\",\"cnRedisUseSsl\":false,\"cnScimProtectionMode\":\"OAUTH\",\"cnSecretKubernetesSecret\":\"cn\",\"cnSqlDbDialect\":\"mysql\",\"cnSqlDbHost\":\"my-release-mysql.default.svc.cluster.local\",\"cnSqlDbName\":\"gluu\",\"cnSqlDbPort\":3306,\"cnSqlDbSchema\":\"\",\"cnSqlDbTimezone\":\"UTC\",\"cnSqlDbUser\":\"gluu\",\"cnSqldbUserPassword\":\"Test1234#\",\"cnVaultAddr\":\"http://localhost:8200\",\"cnVaultAppRolePath\":\"approle\",\"cnVaultKvPath\":\"secret\",\"cnVaultNamespace\":\"\",\"cnVaultPrefix\":\"jans\",\"cnVaultRoleId\":\"\",\"cnVaultRoleIdFile\":\"/etc/certs/vault_role_id\",\"cnVaultSecretId\":\"\",\"cnVaultSecretIdFile\":\"/etc/certs/vault_secret_id\",\"cnVaultVerify\":false,\"kcDbPassword\":\"Test1234#\",\"kcDbSchema\":\"keycloak\",\"kcDbUrlDatabase\":\"keycloak\",\"kcDbUrlHost\":\"mysql.kc.svc.cluster.local\",\"kcDbUrlPort\":3306,\"kcDbUrlProperties\":\"?useUnicode=true&characterEncoding=UTF-8&character_set_server=utf8mb4\",\"kcDbUsername\":\"keycloak\",\"kcDbVendor\":\"mysql\",\"kcLogLevel\":\"INFO\",\"lbAddr\":\"\",\"quarkusTransactionEnableRecovery\":true},\"countryCode\":\"US\",\"customScripts\":[],\"dnsConfig\":{},\"dnsPolicy\":\"\",\"email\":\"team@gluu.org\",\"image\":{\"pullSecrets\":[],\"repository\":\"ghcr.io/janssenproject/jans/configurator\",\"tag\":\"1.1.6_dev\"},\"ldapPassword\":\"P@ssw0rds\",\"ldapTruststorePassword\":\"changeit\",\"lifecycle\":{},\"migration\":{\"enabled\":false,\"migrationDataFormat\":\"ldif\",\"migrationDir\":\"/ce-migration\"},\"orgName\":\"Gluu\",\"redisPassword\":\"P@assw0rd\",\"resources\":{\"limits\":{\"cpu\":\"300m\",\"memory\":\"300Mi\"},\"requests\":{\"cpu\":\"300m\",\"memory\":\"300Mi\"}},\"salt\":\"\",\"state\":\"TX\",\"usrEnvs\":{\"normal\":{},\"secret\":{}},\"volumeMounts\":[],\"volumes\":[]} Configuration parameters for setup and initial configuration secret and config layers used by Gluu services. config-api object {\"additionalAnnotations\":{},\"additionalLabels\":{},\"customScripts\":[],\"dnsConfig\":{},\"dnsPolicy\":\"\",\"hpa\":{\"behavior\":{},\"enabled\":true,\"maxReplicas\":10,\"metrics\":[],\"minReplicas\":1,\"targetCPUUtilizationPercentage\":50},\"image\":{\"pullPolicy\":\"IfNotPresent\",\"pullSecrets\":[],\"repository\":\"ghcr.io/janssenproject/jans/config-api\",\"tag\":\"1.1.6_dev\"},\"lifecycle\":{},\"livenessProbe\":{\"httpGet\":{\"path\":\"/jans-config-api/api/v1/health/live\",\"port\":8074},\"initialDelaySeconds\":30,\"periodSeconds\":30,\"timeoutSeconds\":5},\"pdb\":{\"enabled\":true,\"maxUnavailable\":\"90%\"},\"readinessProbe\":{\"httpGet\":{\"path\":\"jans-config-api/api/v1/health/ready\",\"port\":8074},\"initialDelaySeconds\":25,\"periodSeconds\":25,\"timeoutSeconds\":5},\"replicas\":1,\"resources\":{\"limits\":{\"cpu\":\"1000m\",\"memory\":\"1200Mi\"},\"requests\":{\"cpu\":\"1000m\",\"memory\":\"1200Mi\"}},\"topologySpreadConstraints\":{},\"usrEnvs\":{\"normal\":{},\"secret\":{}},\"volumeMounts\":[],\"volumes\":[]} Config Api endpoints can be used to configure the auth-server, which is an open-source OpenID Connect Provider (OP) and UMA Authorization Server (AS). config-api.additionalAnnotations object {} Additional annotations that will be added across the gateway in the format of config-api.additionalLabels object {} Additional labels that will be added across the gateway in the format of config-api.customScripts list [] Add custom scripts that have been mounted to run before the entrypoint. - /tmp/custom.sh - /tmp/custom2.sh config-api.dnsConfig object {} Add custom dns config config-api.dnsPolicy string \"\" Add custom dns policy config-api.hpa object {\"behavior\":{},\"enabled\":true,\"maxReplicas\":10,\"metrics\":[],\"minReplicas\":1,\"targetCPUUtilizationPercentage\":50} Configure the HorizontalPodAutoscaler config-api.hpa.behavior object {} Scaling Policies config-api.hpa.metrics list [] metrics if targetCPUUtilizationPercentage is not set config-api.image.pullPolicy string \"IfNotPresent\" Image pullPolicy to use for deploying. config-api.image.pullSecrets list [] Image Pull Secrets config-api.image.repository string \"ghcr.io/janssenproject/jans/config-api\" Image to use for deploying. config-api.image.tag string \"1.1.6_dev\" Image tag to use for deploying. config-api.livenessProbe object {\"httpGet\":{\"path\":\"/jans-config-api/api/v1/health/live\",\"port\":8074},\"initialDelaySeconds\":30,\"periodSeconds\":30,\"timeoutSeconds\":5} Configure the liveness healthcheck for the auth server if needed. config-api.livenessProbe.httpGet object {\"path\":\"/jans-config-api/api/v1/health/live\",\"port\":8074} http liveness probe endpoint config-api.pdb object {\"enabled\":true,\"maxUnavailable\":\"90%\"} Configure the PodDisruptionBudget config-api.readinessProbe.httpGet object {\"path\":\"jans-config-api/api/v1/health/ready\",\"port\":8074} http readiness probe endpoint config-api.replicas int 1 Service replica number. config-api.resources object {\"limits\":{\"cpu\":\"1000m\",\"memory\":\"1200Mi\"},\"requests\":{\"cpu\":\"1000m\",\"memory\":\"1200Mi\"}} Resource specs. config-api.resources.limits.cpu string \"1000m\" CPU limit. config-api.resources.limits.memory string \"1200Mi\" Memory limit. This value is used to calculate memory allocation for Java. Currently it only supports Mi . Please refrain from using other units. config-api.resources.requests.cpu string \"1000m\" CPU request. config-api.resources.requests.memory string \"1200Mi\" Memory request. config-api.topologySpreadConstraints object {} Configure the topology spread constraints. Notice this is a map NOT a list as in the upstream API https://kubernetes.io/docs/concepts/scheduling-eviction/topology-spread-constraints/ config-api.usrEnvs object {\"normal\":{},\"secret\":{}} Add custom normal and secret envs to the service config-api.usrEnvs.normal object {} Add custom normal envs to the service variable1: value1 config-api.usrEnvs.secret object {} Add custom secret envs to the service variable1: value1 config-api.volumeMounts list [] Configure any additional volumesMounts that need to be attached to the containers config-api.volumes list [] Configure any additional volumes that need to be attached to the pod config.additionalAnnotations object {} Additional annotations that will be added across the gateway in the format of config.additionalLabels object {} Additional labels that will be added across the gateway in the format of config.adminPassword string \"Test1234#\" Admin password to log in to the UI. config.city string \"Austin\" City. Used for certificate creation. config.configmap.cnCacheType string \"NATIVE_PERSISTENCE\" Cache type. NATIVE_PERSISTENCE , REDIS . or IN_MEMORY . Defaults to NATIVE_PERSISTENCE . config.configmap.cnConfigKubernetesConfigMap string \"cn\" The name of the Kubernetes ConfigMap that will hold the configuration layer config.configmap.cnCouchbaseBucketPrefix string \"jans\" The prefix of couchbase buckets. This helps with separation in between different environments and allows for the same couchbase cluster to be used by different setups of Gluu. config.configmap.cnCouchbaseCrt string \"SWFtTm90YVNlcnZpY2VBY2NvdW50Q2hhbmdlTWV0b09uZQo=\" Couchbase certificate authority string. This must be encoded using base64. This can also be found in your couchbase UI Security > Root Certificate. In mTLS setups this is not required. config.configmap.cnCouchbaseIndexNumReplica int 0 The number of replicas per index created. Please note that the number of index nodes must be one greater than the number of index replicas. That means if your couchbase cluster only has 2 index nodes you cannot place the number of replicas to be higher than 1. config.configmap.cnCouchbasePassword string \"P@ssw0rd\" Couchbase password for the restricted user config.configmap.cnCouchbaseUser that is often used inside the services. The password must contain one digit, one uppercase letter, one lower case letter and one symbol . config.configmap.cnCouchbaseSuperUser string \"admin\" The Couchbase super user (admin) username. This user is used during initialization only. config.configmap.cnCouchbaseSuperUserPassword string \"Test1234#\" Couchbase password for the superuser config.configmap.cnCouchbaseSuperUser that is used during the initialization process. The password must contain one digit, one uppercase letter, one lower case letter and one symbol config.configmap.cnCouchbaseUrl string \"cbgluu.default.svc.cluster.local\" Couchbase URL. Used only when global.cnPersistenceType is hybrid or couchbase. This should be in FQDN format for either remote or local Couchbase clusters. The address can be an internal address inside the kubernetes cluster config.configmap.cnCouchbaseUser string \"gluu\" Couchbase restricted user. Used only when global.cnPersistenceType is hybrid or couchbase. config.configmap.cnGoogleProjectId string \"google-project-to-save-config-and-secrets-to\" Project id of the Google project the secret manager belongs to. Used only when global.configAdapterName and global.configSecretAdapter is set to google. config.configmap.cnGoogleSecretManagerServiceAccount string \"SWFtTm90YVNlcnZpY2VBY2NvdW50Q2hhbmdlTWV0b09uZQo=\" Service account with roles roles/secretmanager.admin base64 encoded string. This is used often inside the services to reach the configuration layer. Used only when global.configAdapterName and global.configSecretAdapter is set to google. config.configmap.cnGoogleSecretNamePrefix string \"gluu\" Prefix for Gluu secret in Google Secret Manager. Defaults to gluu. If left gluu-secret secret will be created. Used only when global.configAdapterName and global.configSecretAdapter is set to google. config.configmap.cnGoogleSecretVersionId string \"latest\" Secret version to be used for secret configuration. Defaults to latest and should normally always stay that way. Used only when global.configAdapterName and global.configSecretAdapter is set to google. config.configmap.cnGoogleSpannerDatabaseId string \"\" Google Spanner Database ID. Used only when global.cnPersistenceType is spanner. config.configmap.cnGoogleSpannerInstanceId string \"\" Google Spanner ID. Used only when global.cnPersistenceType is spanner. config.configmap.cnJettyRequestHeaderSize int 8192 Jetty header size in bytes in the auth server config.configmap.cnLdapCrt string \"SWFtTm90YVNlcnZpY2VBY2NvdW50Q2hhbmdlTWV0b09uZQo=\" OpenDJ certificate string. This must be encoded using base64. config.configmap.cnLdapKey string \"SWFtTm90YVNlcnZpY2VBY2NvdW50Q2hhbmdlTWV0b09uZQo=\" OpenDJ key string. This must be encoded using base64. config.configmap.cnLdapUrl string \"opendj:1636\" OpenDJ internal address. Leave as default. Used when global.cnPersistenceType is set to ldap . config.configmap.cnMaxRamPercent string \"75.0\" Value passed to Java option -XX:MaxRAMPercentage config.configmap.cnMessageType string \"DISABLED\" Message type (one of POSTGRES, REDIS, or DISABLED) config.configmap.cnOpaUrl string \"http://opa.opa.svc.cluster.cluster.local:8181/v1\" URL of OPA API config.configmap.cnPersistenceHybridMapping string \"{}\" Specify data that should be saved in LDAP (one of default, user, cache, site, token, or session; default to default). Note this environment only takes effect when global.cnPersistenceType is set to hybrid . { \"default\": \" 2022-12-20 17:49:55,744 INFO global.auth-server.appLoggers.httpLogLevel string \"INFO\" http_request_response.log level global.auth-server.appLoggers.httpLogTarget string \"FILE\" http_request_response.log target global.auth-server.appLoggers.ldapStatsLogLevel string \"INFO\" jans-auth_persistence_ldap_statistics.log level global.auth-server.appLoggers.ldapStatsLogTarget string \"FILE\" jans-auth_persistence_ldap_statistics.log target global.auth-server.appLoggers.persistenceDurationLogLevel string \"INFO\" jans-auth_persistence_duration.log level global.auth-server.appLoggers.persistenceDurationLogTarget string \"FILE\" jans-auth_persistence_duration.log target global.auth-server.appLoggers.persistenceLogLevel string \"INFO\" jans-auth_persistence.log level global.auth-server.appLoggers.persistenceLogTarget string \"FILE\" jans-auth_persistence.log target global.auth-server.appLoggers.scriptLogLevel string \"INFO\" jans-auth_script.log level global.auth-server.appLoggers.scriptLogTarget string \"FILE\" jans-auth_script.log target global.auth-server.authEncKeys string \"RSA1_5 RSA-OAEP\" space-separated key algorithm for encryption (default to RSA1_5 RSA-OAEP ) global.auth-server.authServerServiceName string \"auth-server\" Name of the auth-server service. Please keep it as default. global.auth-server.authSigKeys string \"RS256 RS384 RS512 ES256 ES384 ES512 PS256 PS384 PS512\" space-separated key algorithm for signing (default to RS256 RS384 RS512 ES256 ES384 ES512 PS256 PS384 PS512 ) global.auth-server.cnCustomJavaOptions string \"\" passing custom java options to auth-server. Notice you do not need to pass in any loggers options as they are introduced below in appLoggers. DO NOT PASS JAVA_OPTIONS in envs. global.auth-server.enabled bool true Boolean flag to enable/disable auth-server chart. You should never set this to false. global.auth-server.ingress object {\"authServerEnabled\":true,\"authServerProtectedRegister\":false,\"authServerProtectedToken\":false,\"deviceCodeEnabled\":true,\"firebaseMessagingEnabled\":true,\"openidConfigEnabled\":true,\"u2fConfigEnabled\":true,\"uma2ConfigEnabled\":true,\"webdiscoveryEnabled\":true,\"webfingerEnabled\":true} Enable endpoints in either istio or nginx ingress depending on users choice global.auth-server.ingress.authServerEnabled bool true Enable Auth server endpoints /jans-auth global.auth-server.ingress.authServerProtectedRegister bool false Enable mTLS onn Auth server endpoint /jans-auth/restv1/register. Currently not working in Istio. global.auth-server.ingress.authServerProtectedToken bool false Enable mTLS on Auth server endpoint /jans-auth/restv1/token. Currently not working in Istio. global.auth-server.ingress.deviceCodeEnabled bool true Enable endpoint /device-code global.auth-server.ingress.firebaseMessagingEnabled bool true Enable endpoint /firebase-messaging-sw.js global.auth-server.ingress.openidConfigEnabled bool true Enable endpoint /.well-known/openid-configuration global.auth-server.ingress.u2fConfigEnabled bool true Enable endpoint /.well-known/fido-configuration global.auth-server.ingress.uma2ConfigEnabled bool true Enable endpoint /.well-known/uma2-configuration global.auth-server.ingress.webdiscoveryEnabled bool true Enable endpoint /.well-known/simple-web-discovery global.auth-server.ingress.webfingerEnabled bool true Enable endpoint /.well-known/webfinger global.auth-server.lockEnabled bool false Enable jans-lock as service running inside auth-server global.awsStorageType string \"io1\" Volume storage type if using AWS volumes. global.azureStorageAccountType string \"Standard_LRS\" Volume storage type if using Azure disks. global.azureStorageKind string \"Managed\" Azure storage kind if using Azure disks global.casa.appLoggers object {\"casaLogLevel\":\"INFO\",\"casaLogTarget\":\"STDOUT\",\"enableStdoutLogPrefix\":\"true\",\"timerLogLevel\":\"INFO\",\"timerLogTarget\":\"FILE\"} App loggers can be configured to define where the logs will be redirected to and the level of each in which it should be displayed. global.casa.appLoggers.casaLogLevel string \"INFO\" casa.log level global.casa.appLoggers.casaLogTarget string \"STDOUT\" casa.log target global.casa.appLoggers.enableStdoutLogPrefix string \"true\" Enable log prefixing which enables prepending the STDOUT logs with the file name. i.e casa ===> 2022-12-20 17:49:55,744 INFO global.casa.appLoggers.timerLogLevel string \"INFO\" casa timer log level global.casa.appLoggers.timerLogTarget string \"FILE\" casa timer log target global.casa.casaServiceName string \"casa\" Name of the casa service. Please keep it as default. global.casa.cnCustomJavaOptions string \"\" passing custom java options to casa. Notice you do not need to pass in any loggers options as they are introduced below in appLoggers. DO NOT PASS JAVA_OPTIONS in envs. global.casa.enabled bool true Boolean flag to enable/disable the casa chart. global.casa.ingress object {\"casaEnabled\":false} Enable endpoints in either istio or nginx ingress depending on users choice global.casa.ingress.casaEnabled bool false Enable casa endpoints /casa global.cloud.testEnviroment bool false Boolean flag if enabled will strip resources requests and limits from all services. global.cnCouchbasePasswordFile string \"/etc/jans/conf/couchbase_password\" Path to Couchbase password file global.cnCouchbaseSuperuserPasswordFile string \"/etc/jans/conf/couchbase_superuser_password\" Path to Couchbase superuser password file global.cnDocumentStoreType string \"DB\" Document store type to use for shibboleth files DB. global.cnGoogleApplicationCredentials string \"/etc/jans/conf/google-credentials.json\" Base64 encoded service account. The sa must have roles/secretmanager.admin to use Google secrets and roles/spanner.databaseUser to use Spanner. Leave as this is a sensible default. global.cnLdapCacertFile string \"/etc/certs/opendj.pem\" Path to OpenDJ CA cert file global.cnLdapCertFile string \"/etc/certs/opendj.crt\" Path to OpenDJ cert file global.cnLdapKeyFile string \"/etc/certs/opendj.key\" Path to OpenDJ key file global.cnLdapPasswordFile string \"/etc/jans/conf/ldap_password\" Path to LDAP password file global.cnLdapTruststoreFile string \"/etc/certs/opendj.pkcs12\" Path to OpenDJ truststore file global.cnLdapTruststorePasswordFile string \"/etc/jans/conf/ldap_truststore_password\" Path to LDAP truststore password file global.cnObExtSigningAlias string \"\" Open banking external signing AS Alias. This is a kid value.Used in SSA Validation, kid used while encoding a JWT sent to token URL i.e. XkwIzWy44xWSlcWnMiEc8iq9s2G global.cnObExtSigningJwksCrt string \"\" Open banking external signing jwks AS certificate authority string. Used in SSA Validation. This must be encoded using base64.. Used when .global.cnObExtSigningJwksUri is set. global.cnObExtSigningJwksKey string \"\" Open banking external signing jwks AS key string. Used in SSA Validation. This must be encoded using base64. Used when .global.cnObExtSigningJwksUri is set. global.cnObExtSigningJwksKeyPassPhrase string \"\" Open banking external signing jwks AS key passphrase to unlock provided key. This must be encoded using base64. Used when .global.cnObExtSigningJwksUri is set. global.cnObExtSigningJwksUri string \"\" Open banking external signing jwks uri. Used in SSA Validation. global.cnObStaticSigningKeyKid string \"\" Open banking signing AS kid to force the AS to use a specific signing key. i.e. Wy44xWSlcWnMiEc8iq9s2G global.cnObTransportAlias string \"\" Open banking transport Alias used inside the JVM. global.cnObTransportCrt string \"\" Open banking AS transport crt. Used in SSA Validation. This must be encoded using base64. global.cnObTransportKey string \"\" Open banking AS transport key. Used in SSA Validation. This must be encoded using base64. global.cnObTransportKeyPassPhrase string \"\" Open banking AS transport key passphrase to unlock AS transport key. This must be encoded using base64. global.cnObTransportTrustStore string \"\" Open banking AS transport truststore crt. This is normally generated from the OB issuing CA, OB Root CA and Signing CA. Used when .global.cnObExtSigningJwksUri is set. Used in SSA Validation. This must be encoded using base64. global.cnPersistenceType string \"sql\" Persistence backend to run Gluu with ldap global.cnPrometheusPort string \"\" Port used by Prometheus JMX agent (default to empty string). To enable Prometheus JMX agent, set the value to a number. global.cnSqlPasswordFile string \"/etc/jans/conf/sql_password\" Path to SQL password file global.config-api.adminUiAppLoggers.adminUiAuditLogLevel string \"INFO\" config-api admin-ui plugin audit log level global.config-api.adminUiAppLoggers.adminUiAuditLogTarget string \"FILE\" config-api admin-ui plugin audit log target global.config-api.adminUiAppLoggers.adminUiLogLevel string \"INFO\" config-api admin-ui plugin log target global.config-api.adminUiAppLoggers.adminUiLogTarget string \"FILE\" config-api admin-ui plugin log level global.config-api.adminUiAppLoggers.enableStdoutLogPrefix string \"true\" Enable log prefixing which enables prepending the STDOUT logs with the file name. i.e config-api_persistence ===> 2022-12-20 17:49:55,744 INFO global.config-api.appLoggers object {\"configApiLogLevel\":\"INFO\",\"configApiLogTarget\":\"STDOUT\",\"enableStdoutLogPrefix\":\"true\",\"ldapStatsLogLevel\":\"INFO\",\"ldapStatsLogTarget\":\"FILE\",\"persistenceDurationLogLevel\":\"INFO\",\"persistenceDurationLogTarget\":\"FILE\",\"persistenceLogLevel\":\"INFO\",\"persistenceLogTarget\":\"FILE\",\"scriptLogLevel\":\"INFO\",\"scriptLogTarget\":\"FILE\"} App loggers can be configured to define where the logs will be redirected to and the level of each in which it should be displayed. global.config-api.appLoggers.configApiLogLevel string \"INFO\" configapi.log level global.config-api.appLoggers.configApiLogTarget string \"STDOUT\" configapi.log target global.config-api.appLoggers.enableStdoutLogPrefix string \"true\" Enable log prefixing which enables prepending the STDOUT logs with the file name. i.e config-api_persistence ===> 2022-12-20 17:49:55,744 INFO global.config-api.appLoggers.ldapStatsLogLevel string \"INFO\" config-api_persistence_ldap_statistics.log level global.config-api.appLoggers.ldapStatsLogTarget string \"FILE\" config-api_persistence_ldap_statistics.log target global.config-api.appLoggers.persistenceDurationLogLevel string \"INFO\" config-api_persistence_duration.log level global.config-api.appLoggers.persistenceDurationLogTarget string \"FILE\" config-api_persistence_duration.log target global.config-api.appLoggers.persistenceLogLevel string \"INFO\" config-api_persistence.log level global.config-api.appLoggers.persistenceLogTarget string \"FILE\" config-api_persistence.log target global.config-api.appLoggers.scriptLogLevel string \"INFO\" config-api_script.log level global.config-api.appLoggers.scriptLogTarget string \"FILE\" config-api_script.log target global.config-api.cnCustomJavaOptions string \"\" passing custom java options to config-api. Notice you do not need to pass in any loggers options as they are introduced below in appLoggers. DO NOT PASS JAVA_OPTIONS in envs. global.config-api.configApiServerServiceName string \"config-api\" Name of the config-api service. Please keep it as default. global.config-api.enabled bool true Boolean flag to enable/disable the config-api chart. global.config-api.ingress object {\"configApiEnabled\":true} Enable endpoints in either istio or nginx ingress depending on users choice global.config-api.plugins string \"admin-ui,fido2,scim,user-mgt\" Comma-separated values of enabled plugins (supported plugins are \"admin-ui\",\"fido2\",\"scim\",\"user-mgt\",\"jans-link\",\"kc-saml\") global.config.enabled bool true Boolean flag to enable/disable the configuration chart. This normally should never be false global.configAdapterName string \"kubernetes\" The config backend adapter that will hold Gluu configuration layer. aws global.configSecretAdapter string \"kubernetes\" The config backend adapter that will hold Gluu secret layer. vault global.distribution string \"default\" Gluu distributions supported are: default global.fido2.appLoggers object {\"enableStdoutLogPrefix\":\"true\",\"fido2LogLevel\":\"INFO\",\"fido2LogTarget\":\"STDOUT\",\"persistenceDurationLogLevel\":\"INFO\",\"persistenceDurationLogTarget\":\"FILE\",\"persistenceLogLevel\":\"INFO\",\"persistenceLogTarget\":\"FILE\",\"scriptLogLevel\":\"INFO\",\"scriptLogTarget\":\"FILE\"} App loggers can be configured to define where the logs will be redirected to and the level of each in which it should be displayed. global.fido2.appLoggers.enableStdoutLogPrefix string \"true\" Enable log prefixing which enables prepending the STDOUT logs with the file name. i.e fido2 ===> 2022-12-20 17:49:55,744 INFO global.fido2.appLoggers.fido2LogLevel string \"INFO\" fido2.log level global.fido2.appLoggers.fido2LogTarget string \"STDOUT\" fido2.log target global.fido2.appLoggers.persistenceDurationLogLevel string \"INFO\" fido2_persistence_duration.log level global.fido2.appLoggers.persistenceDurationLogTarget string \"FILE\" fido2_persistence_duration.log target global.fido2.appLoggers.persistenceLogLevel string \"INFO\" fido2_persistence.log level global.fido2.appLoggers.persistenceLogTarget string \"FILE\" fido2_persistence.log target global.fido2.appLoggers.scriptLogLevel string \"INFO\" fido2_script.log level global.fido2.appLoggers.scriptLogTarget string \"FILE\" fido2_script.log target global.fido2.cnCustomJavaOptions string \"\" passing custom java options to fido2. Notice you do not need to pass in any loggers options as they are introduced below in appLoggers. DO NOT PASS JAVA_OPTIONS in envs. global.fido2.enabled bool true Boolean flag to enable/disable the fido2 chart. global.fido2.fido2ServiceName string \"fido2\" Name of the fido2 service. Please keep it as default. global.fido2.ingress object {\"fido2ConfigEnabled\":false,\"fido2Enabled\":false} Enable endpoints in either istio or nginx ingress depending on users choice global.fido2.ingress.fido2ConfigEnabled bool false Enable endpoint /.well-known/fido2-configuration global.fido2.ingress.fido2Enabled bool false Enable endpoint /jans-fido2 global.fqdn string \"demoexample.gluu.org\" Fully qualified domain name to be used for Gluu installation. This address will be used to reach Gluu services. global.gcePdStorageType string \"pd-standard\" GCE storage kind if using Google disks global.isFqdnRegistered bool false Boolean flag to enable mapping global.lbIp to global.fqdn inside pods on clouds that provide static ip for load balancers. On cloud that provide only addresses to the LB this flag will enable a script to actively scan config.configmap.lbAddr and update the hosts file inside the pods automatically. global.istio.additionalAnnotations object {} Additional annotations that will be added across the gateway in the format of global.istio.additionalLabels object {} Additional labels that will be added across the gateway in the format of global.istio.enabled bool false Boolean flag that enables using istio side-cars with Gluu services. global.istio.gateways list [] Override the gateway that can be created by default. This is used when istio ingress has already been setup and the gateway exists. global.istio.ingress bool false Boolean flag that enables using istio gateway for Gluu. This assumes istio ingress is installed and hence the LB is available. global.istio.namespace string \"istio-system\" The namespace istio is deployed in. The is normally istio-system. global.jobTtlSecondsAfterFinished int 300 https://kubernetes.io/docs/concepts/workloads/controllers/ttlafterfinished/ global.kc-scheduler.enabled bool false Boolean flag to enable/disable the kc-scheduler cronjob chart. global.kcAdminCredentialsFile string \"/etc/jans/conf/kc_admin_creds\" Path to file contains Keycloak admin credentials (username and password) global.kcDbPasswordFile string \"/etc/jans/conf/kc_db_password\" Path to file contains password for database access global.lbIp string \"22.22.22.22\" The Loadbalancer IP created by nginx or istio on clouds that provide static IPs. This is not needed if global.fqdn is globally resolvable. global.link.appLoggers object {\"enableStdoutLogPrefix\":\"true\",\"ldapStatsLogLevel\":\"INFO\",\"ldapStatsLogTarget\":\"FILE\",\"linkLogLevel\":\"INFO\",\"linkLogTarget\":\"STDOUT\",\"persistenceDurationLogLevel\":\"INFO\",\"persistenceDurationLogTarget\":\"FILE\",\"persistenceLogLevel\":\"INFO\",\"persistenceLogTarget\":\"FILE\",\"scriptLogLevel\":\"INFO\",\"scriptLogTarget\":\"FILE\"} App loggers can be configured to define where the logs will be redirected to and the level of each in which it should be displayed. global.link.appLoggers.enableStdoutLogPrefix string \"true\" Enable log prefixing which enables prepending the STDOUT logs with the file name. i.e link-persistence ===> 2022-12-20 17:49:55,744 INFO global.link.appLoggers.ldapStatsLogLevel string \"INFO\" cacherefresh_persistence_ldap_statistics.log level global.link.appLoggers.ldapStatsLogTarget string \"FILE\" cacherefresh_persistence_ldap_statistics.log target global.link.appLoggers.linkLogLevel string \"INFO\" cacherefresh.log level global.link.appLoggers.linkLogTarget string \"STDOUT\" cacherefresh.log target global.link.appLoggers.persistenceDurationLogLevel string \"INFO\" cacherefresh_persistence_duration.log level global.link.appLoggers.persistenceDurationLogTarget string \"FILE\" cacherefresh_persistence_duration.log target global.link.appLoggers.persistenceLogLevel string \"INFO\" cacherefresh_persistence.log level global.link.appLoggers.persistenceLogTarget string \"FILE\" cacherefresh_persistence.log target global.link.appLoggers.scriptLogLevel string \"INFO\" cacherefresh_script.log level global.link.appLoggers.scriptLogTarget string \"FILE\" cacherefresh_script.log target global.link.cnCustomJavaOptions string \"\" passing custom java options to link. Notice you do not need to pass in any loggers options as they are introduced below in appLoggers. DO NOT PASS JAVA_OPTIONS in envs. global.link.enabled bool false Boolean flag to enable/disable the link chart. global.link.ingress object {\"linkEnabled\":true} Enable endpoints in either istio or nginx ingress depending on users choice global.link.linkServiceName string \"link\" Name of the link service. Please keep it as default. global.nginx-ingress.enabled bool true Boolean flag to enable/disable the nginx-ingress definitions chart. global.opendj.enabled bool false Boolean flag to enable/disable the OpenDJ chart. global.opendj.ldapServiceName string \"opendj\" Name of the OpenDJ service. Please keep it as default. global.persistence.enabled bool true Boolean flag to enable/disable the persistence chart. global.saml.cnCustomJavaOptions string \"\" passing custom java options to saml. DO NOT PASS JAVA_OPTIONS in envs. global.saml.enabled bool false Boolean flag to enable/disable the saml chart. global.saml.ingress object {\"samlEnabled\":false} Enable endpoints in either istio or nginx ingress depending on users choice global.saml.samlServiceName string \"saml\" Name of the saml service. Please keep it as default. global.scim.appLoggers object {\"enableStdoutLogPrefix\":\"true\",\"ldapStatsLogLevel\":\"INFO\",\"ldapStatsLogTarget\":\"FILE\",\"persistenceDurationLogLevel\":\"INFO\",\"persistenceDurationLogTarget\":\"FILE\",\"persistenceLogLevel\":\"INFO\",\"persistenceLogTarget\":\"FILE\",\"scimLogLevel\":\"INFO\",\"scimLogTarget\":\"STDOUT\",\"scriptLogLevel\":\"INFO\",\"scriptLogTarget\":\"FILE\"} App loggers can be configured to define where the logs will be redirected to and the level of each in which it should be displayed. global.scim.appLoggers.enableStdoutLogPrefix string \"true\" Enable log prefixing which enables prepending the STDOUT logs with the file name. i.e jans-scim ===> 2022-12-20 17:49:55,744 INFO global.scim.appLoggers.ldapStatsLogLevel string \"INFO\" jans-scim_persistence_ldap_statistics.log level global.scim.appLoggers.ldapStatsLogTarget string \"FILE\" jans-scim_persistence_ldap_statistics.log target global.scim.appLoggers.persistenceDurationLogLevel string \"INFO\" jans-scim_persistence_duration.log level global.scim.appLoggers.persistenceDurationLogTarget string \"FILE\" jans-scim_persistence_duration.log target global.scim.appLoggers.persistenceLogLevel string \"INFO\" jans-scim_persistence.log level global.scim.appLoggers.persistenceLogTarget string \"FILE\" jans-scim_persistence.log target global.scim.appLoggers.scimLogLevel string \"INFO\" jans-scim.log level global.scim.appLoggers.scimLogTarget string \"STDOUT\" jans-scim.log target global.scim.appLoggers.scriptLogLevel string \"INFO\" jans-scim_script.log level global.scim.appLoggers.scriptLogTarget string \"FILE\" jans-scim_script.log target global.scim.cnCustomJavaOptions string \"\" passing custom java options to scim. Notice you do not need to pass in any loggers options as they are introduced below in appLoggers. DO NOT PASS JAVA_OPTIONS in envs. global.scim.enabled bool true Boolean flag to enable/disable the SCIM chart. global.scim.ingress object {\"scimConfigEnabled\":false,\"scimEnabled\":false} Enable endpoints in either istio or nginx ingress depending on users choice global.scim.ingress.scimConfigEnabled bool false Enable endpoint /.well-known/scim-configuration global.scim.ingress.scimEnabled bool false Enable SCIM endpoints /jans-scim global.scim.scimServiceName string \"scim\" Name of the scim service. Please keep it as default. global.storageClass object {\"allowVolumeExpansion\":true,\"allowedTopologies\":[],\"mountOptions\":[\"debug\"],\"parameters\":{},\"provisioner\":\"microk8s.io/hostpath\",\"reclaimPolicy\":\"Retain\",\"volumeBindingMode\":\"WaitForFirstConsumer\"} StorageClass section for OpenDJ charts. This is not currently used by the openbanking distribution. You may specify custom parameters as needed. global.storageClass.parameters object {} parameters: fsType: \"\" kind: \"\" pool: \"\" storageAccountType: \"\" type: \"\" global.usrEnvs object {\"normal\":{},\"secret\":{}} Add custom normal and secret envs to the service. Envs defined in global.userEnvs will be globally available to all services global.usrEnvs.normal object {} Add custom normal envs to the service. variable1: value1 global.usrEnvs.secret object {} Add custom secret envs to the service. variable1: value1 installer-settings object {\"acceptLicense\":\"\",\"aws\":{\"arn\":{\"arnAcmCert\":\"\",\"enabled\":\"\"},\"lbType\":\"\",\"vpcCidr\":\"0.0.0.0/0\"},\"confirmSettings\":false,\"couchbase\":{\"backup\":{\"fullSchedule\":\"\",\"incrementalSchedule\":\"\",\"retentionTime\":\"\",\"storageSize\":\"\"},\"clusterName\":\"\",\"commonName\":\"\",\"customFileOverride\":\"\",\"install\":\"\",\"lowResourceInstall\":\"\",\"namespace\":\"\",\"subjectAlternativeName\":\"\",\"totalNumberOfExpectedTransactionsPerSec\":\"\",\"totalNumberOfExpectedUsers\":\"\",\"volumeType\":\"\"},\"currentVersion\":\"\",\"google\":{\"useSecretManager\":\"\"},\"images\":{\"edit\":\"\"},\"ldap\":{\"backup\":{\"fullSchedule\":\"\"}},\"namespace\":\"\",\"nginxIngress\":{\"namespace\":\"\",\"releaseName\":\"\"},\"nodes\":{\"ips\":\"\",\"names\":\"\",\"zones\":\"\"},\"openbanking\":{\"cnObTransportTrustStoreP12password\":\"\",\"hasCnObTransportTrustStore\":false},\"postgres\":{\"install\":\"\",\"namespace\":\"\"},\"redis\":{\"install\":\"\",\"namespace\":\"\"},\"releaseName\":\"\",\"sql\":{\"install\":\"\",\"namespace\":\"\"},\"volumeProvisionStrategy\":\"\"} Only used by the installer. These settings do not affect nor are used by the chart kc-scheduler object {\"additionalAnnotations\":{},\"additionalLabels\":{},\"customScripts\":[],\"dnsConfig\":{},\"dnsPolicy\":\"\",\"image\":{\"pullPolicy\":\"IfNotPresent\",\"pullSecrets\":[],\"repository\":\"ghcr.io/janssenproject/jans/kc-scheduler\",\"tag\":\"1.1.6_dev\"},\"interval\":10,\"lifecycle\":{},\"resources\":{\"limits\":{\"cpu\":\"300m\",\"memory\":\"300Mi\"},\"requests\":{\"cpu\":\"300m\",\"memory\":\"300Mi\"}},\"usrEnvs\":{\"normal\":{},\"secret\":{}},\"volumeMounts\":[],\"volumes\":[]} Responsible for synchronizing Keycloak SAML clients kc-scheduler.additionalAnnotations object {} Additional annotations that will be added across the gateway in the format of kc-scheduler.additionalLabels object {} Additional labels that will be added across the gateway in the format of kc-scheduler.customScripts list [] Add custom scripts that have been mounted to run before the entrypoint. - /tmp/custom.sh - /tmp/custom2.sh kc-scheduler.dnsConfig object {} Add custom dns config kc-scheduler.dnsPolicy string \"\" Add custom dns policy kc-scheduler.image.pullPolicy string \"IfNotPresent\" Image pullPolicy to use for deploying. kc-scheduler.image.pullSecrets list [] Image Pull Secrets kc-scheduler.image.repository string \"ghcr.io/janssenproject/jans/kc-scheduler\" Image to use for deploying. kc-scheduler.image.tag string \"1.1.6_dev\" Image tag to use for deploying. kc-scheduler.interval int 10 Interval of running the scheduler (in minutes) kc-scheduler.resources object {\"limits\":{\"cpu\":\"300m\",\"memory\":\"300Mi\"},\"requests\":{\"cpu\":\"300m\",\"memory\":\"300Mi\"}} Resource specs. kc-scheduler.resources.limits.cpu string \"300m\" CPU limit. kc-scheduler.resources.limits.memory string \"300Mi\" Memory limit. kc-scheduler.resources.requests.cpu string \"300m\" CPU request. kc-scheduler.resources.requests.memory string \"300Mi\" Memory request. kc-scheduler.usrEnvs object {\"normal\":{},\"secret\":{}} Add custom normal and secret envs to the service kc-scheduler.usrEnvs.normal object {} Add custom normal envs to the service variable1: value1 kc-scheduler.usrEnvs.secret object {} Add custom secret envs to the service variable1: value1 kc-scheduler.volumeMounts list [] Configure any additional volumesMounts that need to be attached to the containers kc-scheduler.volumes list [] Configure any additional volumes that need to be attached to the pod link object {\"additionalAnnotations\":{},\"additionalLabels\":{},\"customScripts\":[],\"dnsConfig\":{},\"dnsPolicy\":\"\",\"hpa\":{\"behavior\":{},\"enabled\":true,\"maxReplicas\":10,\"metrics\":[],\"minReplicas\":1,\"targetCPUUtilizationPercentage\":50},\"image\":{\"pullPolicy\":\"IfNotPresent\",\"pullSecrets\":[],\"repository\":\"ghcr.io/janssenproject/jans/link\",\"tag\":\"1.1.6_dev\"},\"lifecycle\":{},\"livenessProbe\":{\"exec\":{\"command\":[\"python3\",\"/app/scripts/healthcheck.py\"]},\"initialDelaySeconds\":30,\"periodSeconds\":30,\"timeoutSeconds\":5},\"pdb\":{\"enabled\":true,\"maxUnavailable\":\"90%\"},\"readinessProbe\":{\"exec\":{\"command\":[\"python3\",\"/app/scripts/healthcheck.py\"]},\"initialDelaySeconds\":25,\"periodSeconds\":25,\"timeoutSeconds\":5},\"replicas\":1,\"resources\":{\"limits\":{\"cpu\":\"500m\",\"memory\":\"1200Mi\"},\"requests\":{\"cpu\":\"500m\",\"memory\":\"1200Mi\"}},\"topologySpreadConstraints\":{},\"usrEnvs\":{\"normal\":{},\"secret\":{}},\"volumeMounts\":[],\"volumes\":[]} Link. link.additionalAnnotations object {} Additional annotations that will be added across the gateway in the format of link.additionalLabels object {} Additional labels that will be added across the gateway in the format of link.customScripts list [] Add custom scripts that have been mounted to run before the entrypoint. - /tmp/custom.sh - /tmp/custom2.sh link.dnsConfig object {} Add custom dns config link.dnsPolicy string \"\" Add custom dns policy link.hpa object {\"behavior\":{},\"enabled\":true,\"maxReplicas\":10,\"metrics\":[],\"minReplicas\":1,\"targetCPUUtilizationPercentage\":50} Configure the HorizontalPodAutoscaler link.hpa.behavior object {} Scaling Policies link.hpa.metrics list [] metrics if targetCPUUtilizationPercentage is not set link.image.pullPolicy string \"IfNotPresent\" Image pullPolicy to use for deploying. link.image.pullSecrets list [] Image Pull Secrets link.image.repository string \"ghcr.io/janssenproject/jans/link\" Image to use for deploying. link.image.tag string \"1.1.6_dev\" Image tag to use for deploying. link.livenessProbe object {\"exec\":{\"command\":[\"python3\",\"/app/scripts/healthcheck.py\"]},\"initialDelaySeconds\":30,\"periodSeconds\":30,\"timeoutSeconds\":5} Configure the liveness healthcheck for the auth server if needed. link.livenessProbe.exec object {\"command\":[\"python3\",\"/app/scripts/healthcheck.py\"]} http liveness probe endpoint link.pdb object {\"enabled\":true,\"maxUnavailable\":\"90%\"} Configure the PodDisruptionBudget link.readinessProbe.exec object {\"command\":[\"python3\",\"/app/scripts/healthcheck.py\"]} http readiness probe endpoint link.replicas int 1 Service replica number. link.resources object {\"limits\":{\"cpu\":\"500m\",\"memory\":\"1200Mi\"},\"requests\":{\"cpu\":\"500m\",\"memory\":\"1200Mi\"}} Resource specs. link.resources.limits.cpu string \"500m\" CPU limit. link.resources.limits.memory string \"1200Mi\" Memory limit. This value is used to calculate memory allocation for Java. Currently it only supports Mi . Please refrain from using other units. link.resources.requests.cpu string \"500m\" CPU request. link.resources.requests.memory string \"1200Mi\" Memory request. link.topologySpreadConstraints object {} Configure the topology spread constraints. Notice this is a map NOT a list as in the upstream API https://kubernetes.io/docs/concepts/scheduling-eviction/topology-spread-constraints/ link.usrEnvs object {\"normal\":{},\"secret\":{}} Add custom normal and secret envs to the service link.usrEnvs.normal object {} Add custom normal envs to the service variable1: value1 link.usrEnvs.secret object {} Add custom secret envs to the service variable1: value1 link.volumeMounts list [] Configure any additional volumesMounts that need to be attached to the containers link.volumes list [] Configure any additional volumes that need to be attached to the pod nginx-ingress object {\"certManager\":{\"certificate\":{\"enabled\":false,\"issuerGroup\":\"cert-manager.io\",\"issuerKind\":\"ClusterIssuer\",\"issuerName\":\"\"}},\"ingress\":{\"additionalAnnotations\":{},\"additionalLabels\":{},\"adminUiAdditionalAnnotations\":{},\"adminUiLabels\":{},\"authServerAdditionalAnnotations\":{},\"authServerLabels\":{},\"authServerProtectedRegisterAdditionalAnnotations\":{},\"authServerProtectedRegisterLabels\":{},\"authServerProtectedTokenAdditionalAnnotations\":{},\"authServerProtectedTokenLabels\":{},\"casaAdditionalAnnotations\":{},\"casaLabels\":{},\"configApiAdditionalAnnotations\":{},\"configApiLabels\":{},\"deviceCodeAdditionalAnnotations\":{},\"deviceCodeLabels\":{},\"fido2AdditionalAnnotations\":{},\"fido2ConfigAdditionalAnnotations\":{},\"fido2ConfigLabels\":{},\"fido2Labels\":{},\"firebaseMessagingAdditionalAnnotations\":{},\"firebaseMessagingLabels\":{},\"hosts\":[\"demoexample.gluu.org\"],\"ingressClassName\":\"nginx\",\"openidAdditionalAnnotations\":{},\"openidConfigLabels\":{},\"path\":\"/\",\"samlAdditionalAnnotations\":{},\"samlLabels\":{},\"scimAdditionalAnnotations\":{},\"scimConfigAdditionalAnnotations\":{},\"scimConfigLabels\":{},\"scimLabels\":{},\"tls\":[{\"hosts\":[\"demoexample.gluu.org\"],\"secretName\":\"tls-certificate\"}],\"u2fAdditionalAnnotations\":{},\"u2fConfigLabels\":{},\"uma2AdditionalAnnotations\":{},\"uma2ConfigLabels\":{},\"webdiscoveryAdditionalAnnotations\":{},\"webdiscoveryLabels\":{},\"webfingerAdditionalAnnotations\":{},\"webfingerLabels\":{}}} Nginx ingress definitions chart nginx-ingress.ingress.additionalAnnotations object {} Additional annotations that will be added across all ingress definitions in the format of {cert-manager.io/issuer: \"letsencrypt-prod\"} Enable client certificate authentication nginx.ingress.kubernetes.io/auth-tls-verify-client: \"optional\" Create the secret containing the trusted ca certificates nginx.ingress.kubernetes.io/auth-tls-secret: \"gluu/tls-certificate\" Specify the verification depth in the client certificates chain nginx.ingress.kubernetes.io/auth-tls-verify-depth: \"1\" Specify if certificates are passed to upstream server nginx.ingress.kubernetes.io/auth-tls-pass-certificate-to-upstream: \"true\" nginx-ingress.ingress.additionalLabels object {} Additional labels that will be added across all ingress definitions in the format of nginx-ingress.ingress.adminUiAdditionalAnnotations object {} openid-configuration ingress resource additional annotations. nginx-ingress.ingress.adminUiLabels object {} Admin UI ingress resource labels. key app is taken. nginx-ingress.ingress.authServerAdditionalAnnotations object {} Auth server ingress resource additional annotations. nginx-ingress.ingress.authServerLabels object {} Auth server ingress resource labels. key app is taken nginx-ingress.ingress.authServerProtectedRegisterAdditionalAnnotations object {} Auth server protected register ingress resource additional annotations. nginx-ingress.ingress.authServerProtectedRegisterLabels object {} Auth server protected token ingress resource labels. key app is taken nginx-ingress.ingress.authServerProtectedTokenAdditionalAnnotations object {} Auth server protected token ingress resource additional annotations. nginx-ingress.ingress.authServerProtectedTokenLabels object {} Auth server protected token ingress resource labels. key app is taken nginx-ingress.ingress.casaAdditionalAnnotations object {} Casa ingress resource additional annotations. nginx-ingress.ingress.casaLabels object {} Casa ingress resource labels. key app is taken nginx-ingress.ingress.configApiAdditionalAnnotations object {} ConfigAPI ingress resource additional annotations. nginx-ingress.ingress.configApiLabels object {} configAPI ingress resource labels. key app is taken nginx-ingress.ingress.deviceCodeAdditionalAnnotations object {} device-code ingress resource additional annotations. nginx-ingress.ingress.deviceCodeLabels object {} device-code ingress resource labels. key app is taken nginx-ingress.ingress.fido2AdditionalAnnotations object {} fido2 ingress resource additional annotations. nginx-ingress.ingress.fido2ConfigAdditionalAnnotations object {} fido2 config ingress resource additional annotations. nginx-ingress.ingress.fido2ConfigLabels object {} fido2 config ingress resource labels. key app is taken nginx-ingress.ingress.fido2Labels object {} fido2 ingress resource labels. key app is taken nginx-ingress.ingress.firebaseMessagingAdditionalAnnotations object {} Firebase Messaging ingress resource additional annotations. nginx-ingress.ingress.firebaseMessagingLabels object {} Firebase Messaging ingress resource labels. key app is taken nginx-ingress.ingress.openidAdditionalAnnotations object {} openid-configuration ingress resource additional annotations. nginx-ingress.ingress.openidConfigLabels object {} openid-configuration ingress resource labels. key app is taken nginx-ingress.ingress.samlAdditionalAnnotations object {} SAML ingress resource additional annotations. nginx-ingress.ingress.samlLabels object {} SAML config ingress resource labels. key app is taken nginx-ingress.ingress.scimAdditionalAnnotations object {} SCIM ingress resource additional annotations. nginx-ingress.ingress.scimConfigAdditionalAnnotations object {} SCIM config ingress resource additional annotations. nginx-ingress.ingress.scimConfigLabels object {} SCIM config ingress resource labels. key app is taken nginx-ingress.ingress.scimLabels object {} SCIM config ingress resource labels. key app is taken nginx-ingress.ingress.tls list [{\"hosts\":[\"demoexample.gluu.org\"],\"secretName\":\"tls-certificate\"}] Secrets holding HTTPS CA cert and key. nginx-ingress.ingress.u2fAdditionalAnnotations object {} u2f config ingress resource additional annotations. nginx-ingress.ingress.u2fConfigLabels object {} u2f config ingress resource labels. key app is taken nginx-ingress.ingress.uma2AdditionalAnnotations object {} uma2 config ingress resource additional annotations. nginx-ingress.ingress.uma2ConfigLabels object {} uma2 config ingress resource labels. key app is taken nginx-ingress.ingress.webdiscoveryAdditionalAnnotations object {} webdiscovery ingress resource additional annotations. nginx-ingress.ingress.webdiscoveryLabels object {} webdiscovery ingress resource labels. key app is taken nginx-ingress.ingress.webfingerAdditionalAnnotations object {} webfinger ingress resource additional annotations. nginx-ingress.ingress.webfingerLabels object {} webfinger ingress resource labels. key app is taken opendj object {\"additionalAnnotations\":{},\"additionalLabels\":{},\"backup\":{\"cronJobSchedule\":\"*/59 * * * *\",\"enabled\":true},\"customScripts\":[],\"dnsConfig\":{},\"dnsPolicy\":\"\",\"hpa\":{\"behavior\":{},\"enabled\":true,\"maxReplicas\":10,\"metrics\":[],\"minReplicas\":1,\"targetCPUUtilizationPercentage\":50},\"image\":{\"pullPolicy\":\"IfNotPresent\",\"pullSecrets\":[],\"repository\":\"gluufederation/opendj\",\"tag\":\"5.0.0_dev\"},\"lifecycle\":{\"preStop\":{\"exec\":{\"command\":[\"/bin/sh\",\"-c\",\"python3 /app/scripts/deregister_peer.py 1>&/proc/1/fd/1\"]}}},\"livenessProbe\":{\"exec\":{\"command\":[\"python3\",\"/app/scripts/healthcheck.py\"]},\"failureThreshold\":20,\"initialDelaySeconds\":30,\"periodSeconds\":30,\"timeoutSeconds\":5},\"pdb\":{\"enabled\":true,\"maxUnavailable\":1},\"persistence\":{\"size\":\"5Gi\"},\"ports\":{\"tcp-admin\":{\"nodePort\":\"\",\"port\":4444,\"protocol\":\"TCP\",\"targetPort\":4444},\"tcp-ldap\":{\"nodePort\":\"\",\"port\":1389,\"protocol\":\"TCP\",\"targetPort\":1389},\"tcp-ldaps\":{\"nodePort\":\"\",\"port\":1636,\"protocol\":\"TCP\",\"targetPort\":1636},\"tcp-repl\":{\"nodePort\":\"\",\"port\":8989,\"protocol\":\"TCP\",\"targetPort\":8989},\"tcp-serf\":{\"nodePort\":\"\",\"port\":7946,\"protocol\":\"TCP\",\"targetPort\":7946},\"udp-serf\":{\"nodePort\":\"\",\"port\":7946,\"protocol\":\"UDP\",\"targetPort\":7946}},\"readinessProbe\":{\"failureThreshold\":20,\"initialDelaySeconds\":60,\"periodSeconds\":25,\"tcpSocket\":{\"port\":1636},\"timeoutSeconds\":5},\"replicas\":1,\"resources\":{\"limits\":{\"cpu\":\"1500m\",\"memory\":\"2000Mi\"},\"requests\":{\"cpu\":\"1500m\",\"memory\":\"2000Mi\"}},\"topologySpreadConstraints\":{},\"usrEnvs\":{\"normal\":{},\"secret\":{}},\"volumeMounts\":[],\"volumes\":[]} OpenDJ is a directory server which implements a wide range of Lightweight Directory Access Protocol and related standards, including full compliance with LDAPv3 but also support for Directory Service Markup Language (DSMLv2).Written in Java, OpenDJ offers multi-master replication, access control, and many extensions. opendj.additionalAnnotations object {} Additional annotations that will be added across the gateway in the format of opendj.additionalLabels object {} Additional labels that will be added across the gateway in the format of opendj.backup object {\"cronJobSchedule\":\"*/59 * * * *\",\"enabled\":true} Configure ldap backup cronjob opendj.customScripts list [] Add custom scripts that have been mounted to run before the entrypoint. - /tmp/custom.sh - /tmp/custom2.sh opendj.dnsConfig object {} Add custom dns config opendj.dnsPolicy string \"\" Add custom dns policy opendj.hpa object {\"behavior\":{},\"enabled\":true,\"maxReplicas\":10,\"metrics\":[],\"minReplicas\":1,\"targetCPUUtilizationPercentage\":50} Configure the HorizontalPodAutoscaler opendj.hpa.behavior object {} Scaling Policies opendj.hpa.metrics list [] metrics if targetCPUUtilizationPercentage is not set opendj.image.pullPolicy string \"IfNotPresent\" Image pullPolicy to use for deploying. opendj.image.pullSecrets list [] Image Pull Secrets opendj.image.repository string \"gluufederation/opendj\" Image to use for deploying. opendj.image.tag string \"5.0.0_dev\" Image tag to use for deploying. opendj.livenessProbe object {\"exec\":{\"command\":[\"python3\",\"/app/scripts/healthcheck.py\"]},\"failureThreshold\":20,\"initialDelaySeconds\":30,\"periodSeconds\":30,\"timeoutSeconds\":5} Configure the liveness healthcheck for OpenDJ if needed. https://github.com/GluuFederation/docker-opendj/blob/master/scripts/healthcheck.py opendj.livenessProbe.exec object {\"command\":[\"python3\",\"/app/scripts/healthcheck.py\"]} Executes the python3 healthcheck. opendj.pdb object {\"enabled\":true,\"maxUnavailable\":1} Configure the PodDisruptionBudget opendj.persistence.size string \"5Gi\" OpenDJ volume size opendj.readinessProbe object {\"failureThreshold\":20,\"initialDelaySeconds\":60,\"periodSeconds\":25,\"tcpSocket\":{\"port\":1636},\"timeoutSeconds\":5} Configure the readiness healthcheck for OpenDJ if needed. https://github.com/GluuFederation/docker-opendj/blob/master/scripts/healthcheck.py opendj.replicas int 1 Service replica number. opendj.resources object {\"limits\":{\"cpu\":\"1500m\",\"memory\":\"2000Mi\"},\"requests\":{\"cpu\":\"1500m\",\"memory\":\"2000Mi\"}} Resource specs. opendj.resources.limits.cpu string \"1500m\" CPU limit. opendj.resources.limits.memory string \"2000Mi\" Memory limit. opendj.resources.requests.cpu string \"1500m\" CPU request. opendj.resources.requests.memory string \"2000Mi\" Memory request. opendj.topologySpreadConstraints object {} Configure the topology spread constraints. Notice this is a map NOT a list as in the upstream API https://kubernetes.io/docs/concepts/scheduling-eviction/topology-spread-constraints/ opendj.usrEnvs object {\"normal\":{},\"secret\":{}} Add custom normal and secret envs to the service opendj.usrEnvs.normal object {} Add custom normal envs to the service variable1: value1 opendj.usrEnvs.secret object {} Add custom secret envs to the service variable1: value1 opendj.volumeMounts list [] Configure any additional volumesMounts that need to be attached to the containers opendj.volumes list [] Configure any additional volumes that need to be attached to the pod persistence object {\"additionalAnnotations\":{},\"additionalLabels\":{},\"customScripts\":[],\"dnsConfig\":{},\"dnsPolicy\":\"\",\"image\":{\"pullPolicy\":\"IfNotPresent\",\"pullSecrets\":[],\"repository\":\"ghcr.io/janssenproject/jans/persistence-loader\",\"tag\":\"1.1.6_dev\"},\"lifecycle\":{},\"resources\":{\"limits\":{\"cpu\":\"300m\",\"memory\":\"300Mi\"},\"requests\":{\"cpu\":\"300m\",\"memory\":\"300Mi\"}},\"usrEnvs\":{\"normal\":{},\"secret\":{}},\"volumeMounts\":[],\"volumes\":[]} Job to generate data and initial config for Gluu Server persistence layer. persistence.additionalAnnotations object {} Additional annotations that will be added across the gateway in the format of persistence.additionalLabels object {} Additional labels that will be added across the gateway in the format of persistence.customScripts list [] Add custom scripts that have been mounted to run before the entrypoint. - /tmp/custom.sh - /tmp/custom2.sh persistence.dnsConfig object {} Add custom dns config persistence.dnsPolicy string \"\" Add custom dns policy persistence.image.pullPolicy string \"IfNotPresent\" Image pullPolicy to use for deploying. persistence.image.pullSecrets list [] Image Pull Secrets persistence.image.repository string \"ghcr.io/janssenproject/jans/persistence-loader\" Image to use for deploying. persistence.image.tag string \"1.1.6_dev\" Image tag to use for deploying. persistence.resources object {\"limits\":{\"cpu\":\"300m\",\"memory\":\"300Mi\"},\"requests\":{\"cpu\":\"300m\",\"memory\":\"300Mi\"}} Resource specs. persistence.resources.limits.cpu string \"300m\" CPU limit persistence.resources.limits.memory string \"300Mi\" Memory limit. persistence.resources.requests.cpu string \"300m\" CPU request. persistence.resources.requests.memory string \"300Mi\" Memory request. persistence.usrEnvs object {\"normal\":{},\"secret\":{}} Add custom normal and secret envs to the service persistence.usrEnvs.normal object {} Add custom normal envs to the service variable1: value1 persistence.usrEnvs.secret object {} Add custom secret envs to the service variable1: value1 persistence.volumeMounts list [] Configure any additional volumesMounts that need to be attached to the containers persistence.volumes list [] Configure any additional volumes that need to be attached to the pod saml object {\"additionalAnnotations\":{},\"additionalLabels\":{},\"customScripts\":[],\"dnsConfig\":{},\"dnsPolicy\":\"\",\"hpa\":{\"behavior\":{},\"enabled\":true,\"maxReplicas\":10,\"metrics\":[],\"minReplicas\":1,\"targetCPUUtilizationPercentage\":50},\"image\":{\"pullPolicy\":\"IfNotPresent\",\"pullSecrets\":[],\"repository\":\"ghcr.io/janssenproject/jans/saml\",\"tag\":\"1.1.6_dev\"},\"lifecycle\":{},\"livenessProbe\":{\"exec\":{\"command\":[\"python3\",\"/app/scripts/healthcheck.py\"]},\"failureThreshold\":10,\"initialDelaySeconds\":30,\"periodSeconds\":30,\"timeoutSeconds\":5},\"pdb\":{\"enabled\":true,\"maxUnavailable\":\"90%\"},\"readinessProbe\":{\"exec\":{\"command\":[\"python3\",\"/app/scripts/healthcheck.py\"]},\"failureThreshold\":10,\"initialDelaySeconds\":25,\"periodSeconds\":25,\"timeoutSeconds\":5},\"replicas\":1,\"resources\":{\"limits\":{\"cpu\":\"500m\",\"memory\":\"1200Mi\"},\"requests\":{\"cpu\":\"500m\",\"memory\":\"1200Mi\"}},\"topologySpreadConstraints\":{},\"usrEnvs\":{\"normal\":{},\"secret\":{}},\"volumeMounts\":[],\"volumes\":[]} SAML. saml.additionalAnnotations object {} Additional annotations that will be added across the gateway in the format of saml.additionalLabels object {} Additional labels that will be added across the gateway in the format of saml.customScripts list [] Add custom scripts that have been mounted to run before the entrypoint. - /tmp/custom.sh - /tmp/custom2.sh saml.dnsConfig object {} Add custom dns config saml.dnsPolicy string \"\" Add custom dns policy saml.hpa object {\"behavior\":{},\"enabled\":true,\"maxReplicas\":10,\"metrics\":[],\"minReplicas\":1,\"targetCPUUtilizationPercentage\":50} Configure the HorizontalPodAutoscaler saml.hpa.behavior object {} Scaling Policies saml.hpa.metrics list [] metrics if targetCPUUtilizationPercentage is not set saml.image.pullPolicy string \"IfNotPresent\" Image pullPolicy to use for deploying. saml.image.pullSecrets list [] Image Pull Secrets saml.image.repository string \"ghcr.io/janssenproject/jans/saml\" Image to use for deploying. saml.image.tag string \"1.1.6_dev\" Image tag to use for deploying. saml.livenessProbe object {\"exec\":{\"command\":[\"python3\",\"/app/scripts/healthcheck.py\"]},\"failureThreshold\":10,\"initialDelaySeconds\":30,\"periodSeconds\":30,\"timeoutSeconds\":5} Configure the liveness healthcheck for the auth server if needed. saml.livenessProbe.exec object {\"command\":[\"python3\",\"/app/scripts/healthcheck.py\"]} http liveness probe endpoint saml.pdb object {\"enabled\":true,\"maxUnavailable\":\"90%\"} Configure the PodDisruptionBudget saml.readinessProbe.exec object {\"command\":[\"python3\",\"/app/scripts/healthcheck.py\"]} http readiness probe endpoint saml.replicas int 1 Service replica number. saml.resources object {\"limits\":{\"cpu\":\"500m\",\"memory\":\"1200Mi\"},\"requests\":{\"cpu\":\"500m\",\"memory\":\"1200Mi\"}} Resource specs. saml.resources.limits.cpu string \"500m\" CPU limit. saml.resources.limits.memory string \"1200Mi\" Memory limit. This value is used to calculate memory allocation for Java. Currently it only supports Mi . Please refrain from using other units. saml.resources.requests.cpu string \"500m\" CPU request. saml.resources.requests.memory string \"1200Mi\" Memory request. saml.topologySpreadConstraints object {} Configure the topology spread constraints. Notice this is a map NOT a list as in the upstream API https://kubernetes.io/docs/concepts/scheduling-eviction/topology-spread-constraints/ saml.usrEnvs object {\"normal\":{},\"secret\":{}} Add custom normal and secret envs to the service saml.usrEnvs.normal object {} Add custom normal envs to the service variable1: value1 saml.usrEnvs.secret object {} Add custom secret envs to the service variable1: value1 saml.volumeMounts list [] Configure any additional volumesMounts that need to be attached to the containers saml.volumes list [] Configure any additional volumes that need to be attached to the pod scim object {\"additionalAnnotations\":{},\"additionalLabels\":{},\"customScripts\":[],\"dnsConfig\":{},\"dnsPolicy\":\"\",\"hpa\":{\"behavior\":{},\"enabled\":true,\"maxReplicas\":10,\"metrics\":[],\"minReplicas\":1,\"targetCPUUtilizationPercentage\":50},\"image\":{\"pullPolicy\":\"IfNotPresent\",\"pullSecrets\":[],\"repository\":\"ghcr.io/janssenproject/jans/scim\",\"tag\":\"1.1.6_dev\"},\"lifecycle\":{},\"livenessProbe\":{\"httpGet\":{\"path\":\"/jans-scim/sys/health-check\",\"port\":8080},\"initialDelaySeconds\":30,\"periodSeconds\":30,\"timeoutSeconds\":5},\"pdb\":{\"enabled\":true,\"maxUnavailable\":\"90%\"},\"readinessProbe\":{\"httpGet\":{\"path\":\"/jans-scim/sys/health-check\",\"port\":8080},\"initialDelaySeconds\":25,\"periodSeconds\":25,\"timeoutSeconds\":5},\"replicas\":1,\"resources\":{\"limits\":{\"cpu\":\"1000m\",\"memory\":\"1200Mi\"},\"requests\":{\"cpu\":\"1000m\",\"memory\":\"1200Mi\"}},\"service\":{\"name\":\"http-scim\",\"port\":8080},\"topologySpreadConstraints\":{},\"usrEnvs\":{\"normal\":{},\"secret\":{}},\"volumeMounts\":[],\"volumes\":[]} System for Cross-domain Identity Management (SCIM) version 2.0 scim.additionalAnnotations object {} Additional annotations that will be added across the gateway in the format of scim.additionalLabels object {} Additional labels that will be added across the gateway in the format of scim.customScripts list [] Add custom scripts that have been mounted to run before the entrypoint. - /tmp/custom.sh - /tmp/custom2.sh scim.dnsConfig object {} Add custom dns config scim.dnsPolicy string \"\" Add custom dns policy scim.hpa object {\"behavior\":{},\"enabled\":true,\"maxReplicas\":10,\"metrics\":[],\"minReplicas\":1,\"targetCPUUtilizationPercentage\":50} Configure the HorizontalPodAutoscaler scim.hpa.behavior object {} Scaling Policies scim.hpa.metrics list [] metrics if targetCPUUtilizationPercentage is not set scim.image.pullPolicy string \"IfNotPresent\" Image pullPolicy to use for deploying. scim.image.pullSecrets list [] Image Pull Secrets scim.image.repository string \"ghcr.io/janssenproject/jans/scim\" Image to use for deploying. scim.image.tag string \"1.1.6_dev\" Image tag to use for deploying. scim.livenessProbe object {\"httpGet\":{\"path\":\"/jans-scim/sys/health-check\",\"port\":8080},\"initialDelaySeconds\":30,\"periodSeconds\":30,\"timeoutSeconds\":5} Configure the liveness healthcheck for SCIM if needed. scim.livenessProbe.httpGet.path string \"/jans-scim/sys/health-check\" http liveness probe endpoint scim.pdb object {\"enabled\":true,\"maxUnavailable\":\"90%\"} Configure the PodDisruptionBudget scim.readinessProbe object {\"httpGet\":{\"path\":\"/jans-scim/sys/health-check\",\"port\":8080},\"initialDelaySeconds\":25,\"periodSeconds\":25,\"timeoutSeconds\":5} Configure the readiness healthcheck for the SCIM if needed. scim.readinessProbe.httpGet.path string \"/jans-scim/sys/health-check\" http readiness probe endpoint scim.replicas int 1 Service replica number. scim.resources.limits.cpu string \"1000m\" CPU limit. scim.resources.limits.memory string \"1200Mi\" Memory limit. This value is used to calculate memory allocation for Java. Currently it only supports Mi . Please refrain from using other units. scim.resources.requests.cpu string \"1000m\" CPU request. scim.resources.requests.memory string \"1200Mi\" Memory request. scim.service.name string \"http-scim\" The name of the scim port within the scim service. Please keep it as default. scim.service.port int 8080 Port of the scim service. Please keep it as default. scim.topologySpreadConstraints object {} Configure the topology spread constraints. Notice this is a map NOT a list as in the upstream API https://kubernetes.io/docs/concepts/scheduling-eviction/topology-spread-constraints/ scim.usrEnvs object {\"normal\":{},\"secret\":{}} Add custom normal and secret envs to the service scim.usrEnvs.normal object {} Add custom normal envs to the service variable1: value1 scim.usrEnvs.secret object {} Add custom secret envs to the service variable1: value1 scim.volumeMounts list [] Configure any additional volumesMounts that need to be attached to the containers scim.volumes list [] Configure any additional volumes that need to be attached to the pod Autogenerated from chart metadata using helm-docs v1.13.1","title":"Flex Helm Chart"},{"location":"reference/kubernetes/helm-chart/#gluu","text":"Gluu Access and Identity Management Homepage: https://www.gluu.org","title":"gluu"},{"location":"reference/kubernetes/helm-chart/#maintainers","text":"Name Email Url moabu team@gluu.org","title":"Maintainers"},{"location":"reference/kubernetes/helm-chart/#source-code","text":"https://docs.gluu.org","title":"Source Code"},{"location":"reference/kubernetes/helm-chart/#requirements","text":"Kubernetes: >=v1.21.0-0 Repository Name Version admin-ui 5.1.4 auth-server 1.1.4 auth-server-key-rotation 1.1.4 casa 1.1.4 cn-istio-ingress 5.1.4 config 1.1.4 config-api 1.1.4 fido2 1.1.4 kc-scheduler 1.1.4 link 1.1.4 nginx-ingress 5.1.4 persistence 1.1.4 saml 1.1.4 scim 1.1.4","title":"Requirements"},{"location":"reference/kubernetes/helm-chart/#values","text":"Key Type Default Description admin-ui object {\"additionalAnnotations\":{},\"additionalLabels\":{},\"customScripts\":[],\"dnsConfig\":{},\"dnsPolicy\":\"\",\"hpa\":{\"behavior\":{},\"enabled\":true,\"maxReplicas\":10,\"metrics\":[],\"minReplicas\":1,\"targetCPUUtilizationPercentage\":50},\"image\":{\"pullPolicy\":\"IfNotPresent\",\"pullSecrets\":[],\"repository\":\"ghcr.io/gluufederation/flex/admin-ui\",\"tag\":\"5.1.3-1\"},\"lifecycle\":{},\"livenessProbe\":{\"failureThreshold\":20,\"initialDelaySeconds\":60,\"periodSeconds\":25,\"tcpSocket\":{\"port\":8080},\"timeoutSeconds\":5},\"pdb\":{\"enabled\":true,\"maxUnavailable\":\"90%\"},\"readinessProbe\":{\"failureThreshold\":20,\"initialDelaySeconds\":60,\"periodSeconds\":25,\"tcpSocket\":{\"port\":8080},\"timeoutSeconds\":5},\"replicas\":1,\"resources\":{\"limits\":{\"cpu\":\"2000m\",\"memory\":\"2000Mi\"},\"requests\":{\"cpu\":\"2000m\",\"memory\":\"2000Mi\"}},\"topologySpreadConstraints\":{},\"usrEnvs\":{\"normal\":{},\"secret\":{}},\"volumeMounts\":[],\"volumes\":[]} Admin GUI for configuration of the auth-server admin-ui.additionalAnnotations object {} Additional annotations that will be added across the gateway in the format of admin-ui.additionalLabels object {} Additional labels that will be added across the gateway in the format of admin-ui.customScripts list [] Add custom scripts that have been mounted to run before the entrypoint. - /tmp/custom.sh - /tmp/custom2.sh admin-ui.dnsConfig object {} Add custom dns config admin-ui.dnsPolicy string \"\" Add custom dns policy admin-ui.hpa object {\"behavior\":{},\"enabled\":true,\"maxReplicas\":10,\"metrics\":[],\"minReplicas\":1,\"targetCPUUtilizationPercentage\":50} Configure the HorizontalPodAutoscaler admin-ui.hpa.behavior object {} Scaling Policies admin-ui.hpa.metrics list [] metrics if targetCPUUtilizationPercentage is not set admin-ui.image.pullPolicy string \"IfNotPresent\" Image pullPolicy to use for deploying. admin-ui.image.pullSecrets list [] Image Pull Secrets admin-ui.image.repository string \"ghcr.io/gluufederation/flex/admin-ui\" Image to use for deploying. admin-ui.image.tag string \"5.1.3-1\" Image tag to use for deploying. admin-ui.livenessProbe object {\"failureThreshold\":20,\"initialDelaySeconds\":60,\"periodSeconds\":25,\"tcpSocket\":{\"port\":8080},\"timeoutSeconds\":5} Configure the liveness healthcheck for the admin ui if needed. admin-ui.pdb object {\"enabled\":true,\"maxUnavailable\":\"90%\"} Configure the PodDisruptionBudget admin-ui.readinessProbe object {\"failureThreshold\":20,\"initialDelaySeconds\":60,\"periodSeconds\":25,\"tcpSocket\":{\"port\":8080},\"timeoutSeconds\":5} Configure the readiness healthcheck for the admin ui if needed. admin-ui.replicas int 1 Service replica number. admin-ui.resources object {\"limits\":{\"cpu\":\"2000m\",\"memory\":\"2000Mi\"},\"requests\":{\"cpu\":\"2000m\",\"memory\":\"2000Mi\"}} Resource specs. admin-ui.resources.limits.cpu string \"2000m\" CPU limit. admin-ui.resources.limits.memory string \"2000Mi\" Memory limit. admin-ui.resources.requests.cpu string \"2000m\" CPU request. admin-ui.resources.requests.memory string \"2000Mi\" Memory request. admin-ui.topologySpreadConstraints object {} Configure the topology spread constraints. Notice this is a map NOT a list as in the upstream API https://kubernetes.io/docs/concepts/scheduling-eviction/topology-spread-constraints/ admin-ui.usrEnvs object {\"normal\":{},\"secret\":{}} Add custom normal and secret envs to the service admin-ui.usrEnvs.normal object {} Add custom normal envs to the service variable1: value1 admin-ui.usrEnvs.secret object {} Add custom secret envs to the service variable1: value1 admin-ui.volumeMounts list [] Configure any additional volumesMounts that need to be attached to the containers admin-ui.volumes list [] Configure any additional volumes that need to be attached to the pod auth-server object {\"additionalAnnotations\":{},\"additionalLabels\":{},\"customScripts\":[],\"dnsConfig\":{},\"dnsPolicy\":\"\",\"hpa\":{\"behavior\":{},\"enabled\":true,\"maxReplicas\":10,\"metrics\":[],\"minReplicas\":1,\"targetCPUUtilizationPercentage\":50},\"image\":{\"pullPolicy\":\"IfNotPresent\",\"pullSecrets\":[],\"repository\":\"ghcr.io/janssenproject/jans/auth-server\",\"tag\":\"1.1.6_dev\"},\"lifecycle\":{},\"livenessProbe\":{\"exec\":{\"command\":[\"python3\",\"/app/scripts/healthcheck.py\"]},\"initialDelaySeconds\":30,\"periodSeconds\":30,\"timeoutSeconds\":5},\"pdb\":{\"enabled\":true,\"maxUnavailable\":\"90%\"},\"readinessProbe\":{\"exec\":{\"command\":[\"python3\",\"/app/scripts/healthcheck.py\"]},\"initialDelaySeconds\":25,\"periodSeconds\":25,\"timeoutSeconds\":5},\"replicas\":1,\"resources\":{\"limits\":{\"cpu\":\"2500m\",\"memory\":\"2500Mi\"},\"requests\":{\"cpu\":\"2500m\",\"memory\":\"2500Mi\"}},\"topologySpreadConstraints\":{},\"usrEnvs\":{\"normal\":{},\"secret\":{}},\"volumeMounts\":[],\"volumes\":[]} OAuth Authorization Server, the OpenID Connect Provider, the UMA Authorization Server--this is the main Internet facing component of Gluu. It's the service that returns tokens, JWT's and identity assertions. This service must be Internet facing. auth-server-key-rotation object {\"additionalAnnotations\":{},\"additionalLabels\":{},\"customScripts\":[],\"dnsConfig\":{},\"dnsPolicy\":\"\",\"image\":{\"pullPolicy\":\"IfNotPresent\",\"pullSecrets\":[],\"repository\":\"ghcr.io/janssenproject/jans/certmanager\",\"tag\":\"1.1.6_dev\"},\"keysLife\":48,\"keysPushDelay\":0,\"keysPushStrategy\":\"NEWER\",\"keysStrategy\":\"NEWER\",\"lifecycle\":{},\"resources\":{\"limits\":{\"cpu\":\"300m\",\"memory\":\"300Mi\"},\"requests\":{\"cpu\":\"300m\",\"memory\":\"300Mi\"}},\"usrEnvs\":{\"normal\":{},\"secret\":{}},\"volumeMounts\":[],\"volumes\":[]} Responsible for regenerating auth-keys per x hours auth-server-key-rotation.additionalAnnotations object {} Additional annotations that will be added across the gateway in the format of auth-server-key-rotation.additionalLabels object {} Additional labels that will be added across the gateway in the format of auth-server-key-rotation.customScripts list [] Add custom scripts that have been mounted to run before the entrypoint. - /tmp/custom.sh - /tmp/custom2.sh auth-server-key-rotation.dnsConfig object {} Add custom dns config auth-server-key-rotation.dnsPolicy string \"\" Add custom dns policy auth-server-key-rotation.image.pullPolicy string \"IfNotPresent\" Image pullPolicy to use for deploying. auth-server-key-rotation.image.pullSecrets list [] Image Pull Secrets auth-server-key-rotation.image.repository string \"ghcr.io/janssenproject/jans/certmanager\" Image to use for deploying. auth-server-key-rotation.image.tag string \"1.1.3-1\" Image tag to use for deploying. auth-server-key-rotation.keysLife int 48 Auth server key rotation keys life in hours auth-server-key-rotation.keysPushDelay int 0 Delay (in seconds) before pushing private keys to Auth server auth-server-key-rotation.keysPushStrategy string \"NEWER\" Set key selection strategy after pushing private keys to Auth server (only takes effect when keysPushDelay value is greater than 0) auth-server-key-rotation.keysStrategy string \"NEWER\" Set key selection strategy used by Auth server auth-server-key-rotation.resources object {\"limits\":{\"cpu\":\"300m\",\"memory\":\"300Mi\"},\"requests\":{\"cpu\":\"300m\",\"memory\":\"300Mi\"}} Resource specs. auth-server-key-rotation.resources.limits.cpu string \"300m\" CPU limit. auth-server-key-rotation.resources.limits.memory string \"300Mi\" Memory limit. auth-server-key-rotation.resources.requests.cpu string \"300m\" CPU request. auth-server-key-rotation.resources.requests.memory string \"300Mi\" Memory request. auth-server-key-rotation.usrEnvs object {\"normal\":{},\"secret\":{}} Add custom normal and secret envs to the service auth-server-key-rotation.usrEnvs.normal object {} Add custom normal envs to the service variable1: value1 auth-server-key-rotation.usrEnvs.secret object {} Add custom secret envs to the service variable1: value1 auth-server-key-rotation.volumeMounts list [] Configure any additional volumesMounts that need to be attached to the containers auth-server-key-rotation.volumes list [] Configure any additional volumes that need to be attached to the pod auth-server.additionalAnnotations object {} Additional annotations that will be added across the gateway in the format of auth-server.additionalLabels object {} Additional labels that will be added across the gateway in the format of auth-server.customScripts list [] Add custom scripts that have been mounted to run before the entrypoint. - /tmp/custom.sh - /tmp/custom2.sh auth-server.dnsConfig object {} Add custom dns config auth-server.dnsPolicy string \"\" Add custom dns policy auth-server.hpa object {\"behavior\":{},\"enabled\":true,\"maxReplicas\":10,\"metrics\":[],\"minReplicas\":1,\"targetCPUUtilizationPercentage\":50} Configure the HorizontalPodAutoscaler auth-server.hpa.behavior object {} Scaling Policies auth-server.hpa.metrics list [] metrics if targetCPUUtilizationPercentage is not set auth-server.image.pullPolicy string \"IfNotPresent\" Image pullPolicy to use for deploying. auth-server.image.pullSecrets list [] Image Pull Secrets auth-server.image.repository string \"ghcr.io/janssenproject/jans/auth-server\" Image to use for deploying. auth-server.image.tag string \"1.1.6_dev\" Image tag to use for deploying. auth-server.livenessProbe object {\"exec\":{\"command\":[\"python3\",\"/app/scripts/healthcheck.py\"]},\"initialDelaySeconds\":30,\"periodSeconds\":30,\"timeoutSeconds\":5} Configure the liveness healthcheck for the auth server if needed. auth-server.livenessProbe.exec object {\"command\":[\"python3\",\"/app/scripts/healthcheck.py\"]} Executes the python3 healthcheck. https://github.com/JanssenProject/docker-jans-auth-server/blob/master/scripts/healthcheck.py auth-server.pdb object {\"enabled\":true,\"maxUnavailable\":\"90%\"} Configure the PodDisruptionBudget auth-server.readinessProbe object {\"exec\":{\"command\":[\"python3\",\"/app/scripts/healthcheck.py\"]},\"initialDelaySeconds\":25,\"periodSeconds\":25,\"timeoutSeconds\":5} Configure the readiness healthcheck for the auth server if needed. https://github.com/JanssenProject/docker-jans-auth-server/blob/master/scripts/healthcheck.py auth-server.replicas int 1 Service replica number. auth-server.resources object {\"limits\":{\"cpu\":\"2500m\",\"memory\":\"2500Mi\"},\"requests\":{\"cpu\":\"2500m\",\"memory\":\"2500Mi\"}} Resource specs. auth-server.resources.limits.cpu string \"2500m\" CPU limit. auth-server.resources.limits.memory string \"2500Mi\" Memory limit. This value is used to calculate memory allocation for Java. Currently it only supports Mi . Please refrain from using other units. auth-server.resources.requests.cpu string \"2500m\" CPU request. auth-server.resources.requests.memory string \"2500Mi\" Memory request. auth-server.topologySpreadConstraints object {} Configure the topology spread constraints. Notice this is a map NOT a list as in the upstream API https://kubernetes.io/docs/concepts/scheduling-eviction/topology-spread-constraints/ auth-server.usrEnvs object {\"normal\":{},\"secret\":{}} Add custom normal and secret envs to the service auth-server.usrEnvs.normal object {} Add custom normal envs to the service variable1: value1 auth-server.usrEnvs.secret object {} Add custom secret envs to the service variable1: value1 auth-server.volumeMounts list [] Configure any additional volumesMounts that need to be attached to the containers auth-server.volumes list [] Configure any additional volumes that need to be attached to the pod casa object {\"additionalAnnotations\":{},\"additionalLabels\":{},\"customScripts\":[],\"dnsConfig\":{},\"dnsPolicy\":\"\",\"hpa\":{\"behavior\":{},\"enabled\":true,\"maxReplicas\":10,\"metrics\":[],\"minReplicas\":1,\"targetCPUUtilizationPercentage\":50},\"image\":{\"pullPolicy\":\"IfNotPresent\",\"pullSecrets\":[],\"repository\":\"ghcr.io/janssenproject/jans/casa\",\"tag\":\"1.1.6_dev\"},\"lifecycle\":{},\"livenessProbe\":{\"httpGet\":{\"path\":\"/jans-casa/health-check\",\"port\":\"http-casa\"},\"initialDelaySeconds\":25,\"periodSeconds\":25,\"timeoutSeconds\":5},\"pdb\":{\"enabled\":true,\"maxUnavailable\":\"90%\"},\"readinessProbe\":{\"httpGet\":{\"path\":\"/jans-casa/health-check\",\"port\":\"http-casa\"},\"initialDelaySeconds\":30,\"periodSeconds\":30,\"timeoutSeconds\":5},\"replicas\":1,\"resources\":{\"limits\":{\"cpu\":\"500m\",\"memory\":\"500Mi\"},\"requests\":{\"cpu\":\"500m\",\"memory\":\"500Mi\"}},\"topologySpreadConstraints\":{},\"usrEnvs\":{\"normal\":{},\"secret\":{}},\"volumeMounts\":[],\"volumes\":[]} Janssen Casa (\"Casa\") is a self-service web portal for end-users to manage authentication and authorization preferences for their account in a Janssen Auth Server. casa.additionalAnnotations object {} Additional annotations that will be added across the gateway in the format of casa.additionalLabels object {} Additional labels that will be added across the gateway in the format of casa.customScripts list [] Add custom scripts that have been mounted to run before the entrypoint. - /tmp/custom.sh - /tmp/custom2.sh casa.dnsConfig object {} Add custom dns config casa.dnsPolicy string \"\" Add custom dns policy casa.hpa object {\"behavior\":{},\"enabled\":true,\"maxReplicas\":10,\"metrics\":[],\"minReplicas\":1,\"targetCPUUtilizationPercentage\":50} Configure the HorizontalPodAutoscaler casa.hpa.behavior object {} Scaling Policies casa.hpa.metrics list [] metrics if targetCPUUtilizationPercentage is not set casa.image.pullPolicy string \"IfNotPresent\" Image pullPolicy to use for deploying. casa.image.pullSecrets list [] Image Pull Secrets casa.image.repository string \"ghcr.io/janssenproject/jans/casa\" Image to use for deploying. casa.image.tag string \"1.1.6_dev\" Image tag to use for deploying. casa.livenessProbe object {\"httpGet\":{\"path\":\"/jans-casa/health-check\",\"port\":\"http-casa\"},\"initialDelaySeconds\":25,\"periodSeconds\":25,\"timeoutSeconds\":5} Configure the liveness healthcheck for casa if needed. casa.livenessProbe.httpGet.path string \"/jans-casa/health-check\" http liveness probe endpoint casa.pdb object {\"enabled\":true,\"maxUnavailable\":\"90%\"} Configure the PodDisruptionBudget casa.readinessProbe object {\"httpGet\":{\"path\":\"/jans-casa/health-check\",\"port\":\"http-casa\"},\"initialDelaySeconds\":30,\"periodSeconds\":30,\"timeoutSeconds\":5} Configure the readiness healthcheck for the casa if needed. casa.readinessProbe.httpGet.path string \"/jans-casa/health-check\" http readiness probe endpoint casa.replicas int 1 Service replica number. casa.resources object {\"limits\":{\"cpu\":\"500m\",\"memory\":\"500Mi\"},\"requests\":{\"cpu\":\"500m\",\"memory\":\"500Mi\"}} Resource specs. casa.resources.limits.cpu string \"500m\" CPU limit. casa.resources.limits.memory string \"500Mi\" Memory limit. This value is used to calculate memory allocation for Java. Currently it only supports Mi . Please refrain from using other units. casa.resources.requests.cpu string \"500m\" CPU request. casa.resources.requests.memory string \"500Mi\" Memory request. casa.topologySpreadConstraints object {} Configure the topology spread constraints. Notice this is a map NOT a list as in the upstream API https://kubernetes.io/docs/concepts/scheduling-eviction/topology-spread-constraints/ casa.usrEnvs object {\"normal\":{},\"secret\":{}} Add custom normal and secret envs to the service casa.usrEnvs.normal object {} Add custom normal envs to the service variable1: value1 casa.usrEnvs.secret object {} Add custom secret envs to the service variable1: value1 casa.volumeMounts list [] Configure any additional volumesMounts that need to be attached to the containers casa.volumes list [] Configure any additional volumes that need to be attached to the pod config object {\"additionalAnnotations\":{},\"additionalLabels\":{},\"adminPassword\":\"Test1234#\",\"city\":\"Austin\",\"configmap\":{\"cnAwsAccessKeyId\":\"\",\"cnAwsDefaultRegion\":\"us-west-1\",\"cnAwsProfile\":\"gluu\",\"cnAwsSecretAccessKey\":\"\",\"cnAwsSecretsEndpointUrl\":\"\",\"cnAwsSecretsNamePrefix\":\"gluu\",\"cnAwsSecretsReplicaRegions\":[],\"cnCacheType\":\"NATIVE_PERSISTENCE\",\"cnConfigKubernetesConfigMap\":\"cn\",\"cnCouchbaseBucketPrefix\":\"jans\",\"cnCouchbaseCrt\":\"SWFtTm90YVNlcnZpY2VBY2NvdW50Q2hhbmdlTWV0b09uZQo=\",\"cnCouchbaseIndexNumReplica\":0,\"cnCouchbasePassword\":\"P@ssw0rd\",\"cnCouchbaseSuperUser\":\"admin\",\"cnCouchbaseSuperUserPassword\":\"Test1234#\",\"cnCouchbaseUrl\":\"cbgluu.default.svc.cluster.local\",\"cnCouchbaseUser\":\"gluu\",\"cnGoogleProjectId\":\"google-project-to-save-config-and-secrets-to\",\"cnGoogleSecretManagerServiceAccount\":\"SWFtTm90YVNlcnZpY2VBY2NvdW50Q2hhbmdlTWV0b09uZQo=\",\"cnGoogleSecretNamePrefix\":\"gluu\",\"cnGoogleSecretVersionId\":\"latest\",\"cnGoogleSpannerDatabaseId\":\"\",\"cnGoogleSpannerInstanceId\":\"\",\"cnJettyRequestHeaderSize\":8192,\"cnLdapCrt\":\"SWFtTm90YVNlcnZpY2VBY2NvdW50Q2hhbmdlTWV0b09uZQo=\",\"cnLdapKey\":\"SWFtTm90YVNlcnZpY2VBY2NvdW50Q2hhbmdlTWV0b09uZQo=\",\"cnLdapUrl\":\"opendj:1636\",\"cnMaxRamPercent\":\"75.0\",\"cnMessageType\":\"DISABLED\",\"cnOpaUrl\":\"http://opa.opa.svc.cluster.cluster.local:8181/v1\",\"cnPersistenceHybridMapping\":\"{}\",\"cnRedisSentinelGroup\":\"\",\"cnRedisSslTruststore\":\"\",\"cnRedisType\":\"STANDALONE\",\"cnRedisUrl\":\"redis.redis.svc.cluster.local:6379\",\"cnRedisUseSsl\":false,\"cnScimProtectionMode\":\"OAUTH\",\"cnSecretKubernetesSecret\":\"cn\",\"cnSqlDbDialect\":\"mysql\",\"cnSqlDbHost\":\"my-release-mysql.default.svc.cluster.local\",\"cnSqlDbName\":\"gluu\",\"cnSqlDbPort\":3306,\"cnSqlDbSchema\":\"\",\"cnSqlDbTimezone\":\"UTC\",\"cnSqlDbUser\":\"gluu\",\"cnSqldbUserPassword\":\"Test1234#\",\"cnVaultAddr\":\"http://localhost:8200\",\"cnVaultAppRolePath\":\"approle\",\"cnVaultKvPath\":\"secret\",\"cnVaultNamespace\":\"\",\"cnVaultPrefix\":\"jans\",\"cnVaultRoleId\":\"\",\"cnVaultRoleIdFile\":\"/etc/certs/vault_role_id\",\"cnVaultSecretId\":\"\",\"cnVaultSecretIdFile\":\"/etc/certs/vault_secret_id\",\"cnVaultVerify\":false,\"kcDbPassword\":\"Test1234#\",\"kcDbSchema\":\"keycloak\",\"kcDbUrlDatabase\":\"keycloak\",\"kcDbUrlHost\":\"mysql.kc.svc.cluster.local\",\"kcDbUrlPort\":3306,\"kcDbUrlProperties\":\"?useUnicode=true&characterEncoding=UTF-8&character_set_server=utf8mb4\",\"kcDbUsername\":\"keycloak\",\"kcDbVendor\":\"mysql\",\"kcLogLevel\":\"INFO\",\"lbAddr\":\"\",\"quarkusTransactionEnableRecovery\":true},\"countryCode\":\"US\",\"customScripts\":[],\"dnsConfig\":{},\"dnsPolicy\":\"\",\"email\":\"team@gluu.org\",\"image\":{\"pullSecrets\":[],\"repository\":\"ghcr.io/janssenproject/jans/configurator\",\"tag\":\"1.1.6_dev\"},\"ldapPassword\":\"P@ssw0rds\",\"ldapTruststorePassword\":\"changeit\",\"lifecycle\":{},\"migration\":{\"enabled\":false,\"migrationDataFormat\":\"ldif\",\"migrationDir\":\"/ce-migration\"},\"orgName\":\"Gluu\",\"redisPassword\":\"P@assw0rd\",\"resources\":{\"limits\":{\"cpu\":\"300m\",\"memory\":\"300Mi\"},\"requests\":{\"cpu\":\"300m\",\"memory\":\"300Mi\"}},\"salt\":\"\",\"state\":\"TX\",\"usrEnvs\":{\"normal\":{},\"secret\":{}},\"volumeMounts\":[],\"volumes\":[]} Configuration parameters for setup and initial configuration secret and config layers used by Gluu services. config-api object {\"additionalAnnotations\":{},\"additionalLabels\":{},\"customScripts\":[],\"dnsConfig\":{},\"dnsPolicy\":\"\",\"hpa\":{\"behavior\":{},\"enabled\":true,\"maxReplicas\":10,\"metrics\":[],\"minReplicas\":1,\"targetCPUUtilizationPercentage\":50},\"image\":{\"pullPolicy\":\"IfNotPresent\",\"pullSecrets\":[],\"repository\":\"ghcr.io/janssenproject/jans/config-api\",\"tag\":\"1.1.6_dev\"},\"lifecycle\":{},\"livenessProbe\":{\"httpGet\":{\"path\":\"/jans-config-api/api/v1/health/live\",\"port\":8074},\"initialDelaySeconds\":30,\"periodSeconds\":30,\"timeoutSeconds\":5},\"pdb\":{\"enabled\":true,\"maxUnavailable\":\"90%\"},\"readinessProbe\":{\"httpGet\":{\"path\":\"jans-config-api/api/v1/health/ready\",\"port\":8074},\"initialDelaySeconds\":25,\"periodSeconds\":25,\"timeoutSeconds\":5},\"replicas\":1,\"resources\":{\"limits\":{\"cpu\":\"1000m\",\"memory\":\"1200Mi\"},\"requests\":{\"cpu\":\"1000m\",\"memory\":\"1200Mi\"}},\"topologySpreadConstraints\":{},\"usrEnvs\":{\"normal\":{},\"secret\":{}},\"volumeMounts\":[],\"volumes\":[]} Config Api endpoints can be used to configure the auth-server, which is an open-source OpenID Connect Provider (OP) and UMA Authorization Server (AS). config-api.additionalAnnotations object {} Additional annotations that will be added across the gateway in the format of config-api.additionalLabels object {} Additional labels that will be added across the gateway in the format of config-api.customScripts list [] Add custom scripts that have been mounted to run before the entrypoint. - /tmp/custom.sh - /tmp/custom2.sh config-api.dnsConfig object {} Add custom dns config config-api.dnsPolicy string \"\" Add custom dns policy config-api.hpa object {\"behavior\":{},\"enabled\":true,\"maxReplicas\":10,\"metrics\":[],\"minReplicas\":1,\"targetCPUUtilizationPercentage\":50} Configure the HorizontalPodAutoscaler config-api.hpa.behavior object {} Scaling Policies config-api.hpa.metrics list [] metrics if targetCPUUtilizationPercentage is not set config-api.image.pullPolicy string \"IfNotPresent\" Image pullPolicy to use for deploying. config-api.image.pullSecrets list [] Image Pull Secrets config-api.image.repository string \"ghcr.io/janssenproject/jans/config-api\" Image to use for deploying. config-api.image.tag string \"1.1.6_dev\" Image tag to use for deploying. config-api.livenessProbe object {\"httpGet\":{\"path\":\"/jans-config-api/api/v1/health/live\",\"port\":8074},\"initialDelaySeconds\":30,\"periodSeconds\":30,\"timeoutSeconds\":5} Configure the liveness healthcheck for the auth server if needed. config-api.livenessProbe.httpGet object {\"path\":\"/jans-config-api/api/v1/health/live\",\"port\":8074} http liveness probe endpoint config-api.pdb object {\"enabled\":true,\"maxUnavailable\":\"90%\"} Configure the PodDisruptionBudget config-api.readinessProbe.httpGet object {\"path\":\"jans-config-api/api/v1/health/ready\",\"port\":8074} http readiness probe endpoint config-api.replicas int 1 Service replica number. config-api.resources object {\"limits\":{\"cpu\":\"1000m\",\"memory\":\"1200Mi\"},\"requests\":{\"cpu\":\"1000m\",\"memory\":\"1200Mi\"}} Resource specs. config-api.resources.limits.cpu string \"1000m\" CPU limit. config-api.resources.limits.memory string \"1200Mi\" Memory limit. This value is used to calculate memory allocation for Java. Currently it only supports Mi . Please refrain from using other units. config-api.resources.requests.cpu string \"1000m\" CPU request. config-api.resources.requests.memory string \"1200Mi\" Memory request. config-api.topologySpreadConstraints object {} Configure the topology spread constraints. Notice this is a map NOT a list as in the upstream API https://kubernetes.io/docs/concepts/scheduling-eviction/topology-spread-constraints/ config-api.usrEnvs object {\"normal\":{},\"secret\":{}} Add custom normal and secret envs to the service config-api.usrEnvs.normal object {} Add custom normal envs to the service variable1: value1 config-api.usrEnvs.secret object {} Add custom secret envs to the service variable1: value1 config-api.volumeMounts list [] Configure any additional volumesMounts that need to be attached to the containers config-api.volumes list [] Configure any additional volumes that need to be attached to the pod config.additionalAnnotations object {} Additional annotations that will be added across the gateway in the format of config.additionalLabels object {} Additional labels that will be added across the gateway in the format of config.adminPassword string \"Test1234#\" Admin password to log in to the UI. config.city string \"Austin\" City. Used for certificate creation. config.configmap.cnCacheType string \"NATIVE_PERSISTENCE\" Cache type. NATIVE_PERSISTENCE , REDIS . or IN_MEMORY . Defaults to NATIVE_PERSISTENCE . config.configmap.cnConfigKubernetesConfigMap string \"cn\" The name of the Kubernetes ConfigMap that will hold the configuration layer config.configmap.cnCouchbaseBucketPrefix string \"jans\" The prefix of couchbase buckets. This helps with separation in between different environments and allows for the same couchbase cluster to be used by different setups of Gluu. config.configmap.cnCouchbaseCrt string \"SWFtTm90YVNlcnZpY2VBY2NvdW50Q2hhbmdlTWV0b09uZQo=\" Couchbase certificate authority string. This must be encoded using base64. This can also be found in your couchbase UI Security > Root Certificate. In mTLS setups this is not required. config.configmap.cnCouchbaseIndexNumReplica int 0 The number of replicas per index created. Please note that the number of index nodes must be one greater than the number of index replicas. That means if your couchbase cluster only has 2 index nodes you cannot place the number of replicas to be higher than 1. config.configmap.cnCouchbasePassword string \"P@ssw0rd\" Couchbase password for the restricted user config.configmap.cnCouchbaseUser that is often used inside the services. The password must contain one digit, one uppercase letter, one lower case letter and one symbol . config.configmap.cnCouchbaseSuperUser string \"admin\" The Couchbase super user (admin) username. This user is used during initialization only. config.configmap.cnCouchbaseSuperUserPassword string \"Test1234#\" Couchbase password for the superuser config.configmap.cnCouchbaseSuperUser that is used during the initialization process. The password must contain one digit, one uppercase letter, one lower case letter and one symbol config.configmap.cnCouchbaseUrl string \"cbgluu.default.svc.cluster.local\" Couchbase URL. Used only when global.cnPersistenceType is hybrid or couchbase. This should be in FQDN format for either remote or local Couchbase clusters. The address can be an internal address inside the kubernetes cluster config.configmap.cnCouchbaseUser string \"gluu\" Couchbase restricted user. Used only when global.cnPersistenceType is hybrid or couchbase. config.configmap.cnGoogleProjectId string \"google-project-to-save-config-and-secrets-to\" Project id of the Google project the secret manager belongs to. Used only when global.configAdapterName and global.configSecretAdapter is set to google. config.configmap.cnGoogleSecretManagerServiceAccount string \"SWFtTm90YVNlcnZpY2VBY2NvdW50Q2hhbmdlTWV0b09uZQo=\" Service account with roles roles/secretmanager.admin base64 encoded string. This is used often inside the services to reach the configuration layer. Used only when global.configAdapterName and global.configSecretAdapter is set to google. config.configmap.cnGoogleSecretNamePrefix string \"gluu\" Prefix for Gluu secret in Google Secret Manager. Defaults to gluu. If left gluu-secret secret will be created. Used only when global.configAdapterName and global.configSecretAdapter is set to google. config.configmap.cnGoogleSecretVersionId string \"latest\" Secret version to be used for secret configuration. Defaults to latest and should normally always stay that way. Used only when global.configAdapterName and global.configSecretAdapter is set to google. config.configmap.cnGoogleSpannerDatabaseId string \"\" Google Spanner Database ID. Used only when global.cnPersistenceType is spanner. config.configmap.cnGoogleSpannerInstanceId string \"\" Google Spanner ID. Used only when global.cnPersistenceType is spanner. config.configmap.cnJettyRequestHeaderSize int 8192 Jetty header size in bytes in the auth server config.configmap.cnLdapCrt string \"SWFtTm90YVNlcnZpY2VBY2NvdW50Q2hhbmdlTWV0b09uZQo=\" OpenDJ certificate string. This must be encoded using base64. config.configmap.cnLdapKey string \"SWFtTm90YVNlcnZpY2VBY2NvdW50Q2hhbmdlTWV0b09uZQo=\" OpenDJ key string. This must be encoded using base64. config.configmap.cnLdapUrl string \"opendj:1636\" OpenDJ internal address. Leave as default. Used when global.cnPersistenceType is set to ldap . config.configmap.cnMaxRamPercent string \"75.0\" Value passed to Java option -XX:MaxRAMPercentage config.configmap.cnMessageType string \"DISABLED\" Message type (one of POSTGRES, REDIS, or DISABLED) config.configmap.cnOpaUrl string \"http://opa.opa.svc.cluster.cluster.local:8181/v1\" URL of OPA API config.configmap.cnPersistenceHybridMapping string \"{}\" Specify data that should be saved in LDAP (one of default, user, cache, site, token, or session; default to default). Note this environment only takes effect when global.cnPersistenceType is set to hybrid . { \"default\": \" 2022-12-20 17:49:55,744 INFO global.auth-server.appLoggers.httpLogLevel string \"INFO\" http_request_response.log level global.auth-server.appLoggers.httpLogTarget string \"FILE\" http_request_response.log target global.auth-server.appLoggers.ldapStatsLogLevel string \"INFO\" jans-auth_persistence_ldap_statistics.log level global.auth-server.appLoggers.ldapStatsLogTarget string \"FILE\" jans-auth_persistence_ldap_statistics.log target global.auth-server.appLoggers.persistenceDurationLogLevel string \"INFO\" jans-auth_persistence_duration.log level global.auth-server.appLoggers.persistenceDurationLogTarget string \"FILE\" jans-auth_persistence_duration.log target global.auth-server.appLoggers.persistenceLogLevel string \"INFO\" jans-auth_persistence.log level global.auth-server.appLoggers.persistenceLogTarget string \"FILE\" jans-auth_persistence.log target global.auth-server.appLoggers.scriptLogLevel string \"INFO\" jans-auth_script.log level global.auth-server.appLoggers.scriptLogTarget string \"FILE\" jans-auth_script.log target global.auth-server.authEncKeys string \"RSA1_5 RSA-OAEP\" space-separated key algorithm for encryption (default to RSA1_5 RSA-OAEP ) global.auth-server.authServerServiceName string \"auth-server\" Name of the auth-server service. Please keep it as default. global.auth-server.authSigKeys string \"RS256 RS384 RS512 ES256 ES384 ES512 PS256 PS384 PS512\" space-separated key algorithm for signing (default to RS256 RS384 RS512 ES256 ES384 ES512 PS256 PS384 PS512 ) global.auth-server.cnCustomJavaOptions string \"\" passing custom java options to auth-server. Notice you do not need to pass in any loggers options as they are introduced below in appLoggers. DO NOT PASS JAVA_OPTIONS in envs. global.auth-server.enabled bool true Boolean flag to enable/disable auth-server chart. You should never set this to false. global.auth-server.ingress object {\"authServerEnabled\":true,\"authServerProtectedRegister\":false,\"authServerProtectedToken\":false,\"deviceCodeEnabled\":true,\"firebaseMessagingEnabled\":true,\"openidConfigEnabled\":true,\"u2fConfigEnabled\":true,\"uma2ConfigEnabled\":true,\"webdiscoveryEnabled\":true,\"webfingerEnabled\":true} Enable endpoints in either istio or nginx ingress depending on users choice global.auth-server.ingress.authServerEnabled bool true Enable Auth server endpoints /jans-auth global.auth-server.ingress.authServerProtectedRegister bool false Enable mTLS onn Auth server endpoint /jans-auth/restv1/register. Currently not working in Istio. global.auth-server.ingress.authServerProtectedToken bool false Enable mTLS on Auth server endpoint /jans-auth/restv1/token. Currently not working in Istio. global.auth-server.ingress.deviceCodeEnabled bool true Enable endpoint /device-code global.auth-server.ingress.firebaseMessagingEnabled bool true Enable endpoint /firebase-messaging-sw.js global.auth-server.ingress.openidConfigEnabled bool true Enable endpoint /.well-known/openid-configuration global.auth-server.ingress.u2fConfigEnabled bool true Enable endpoint /.well-known/fido-configuration global.auth-server.ingress.uma2ConfigEnabled bool true Enable endpoint /.well-known/uma2-configuration global.auth-server.ingress.webdiscoveryEnabled bool true Enable endpoint /.well-known/simple-web-discovery global.auth-server.ingress.webfingerEnabled bool true Enable endpoint /.well-known/webfinger global.auth-server.lockEnabled bool false Enable jans-lock as service running inside auth-server global.awsStorageType string \"io1\" Volume storage type if using AWS volumes. global.azureStorageAccountType string \"Standard_LRS\" Volume storage type if using Azure disks. global.azureStorageKind string \"Managed\" Azure storage kind if using Azure disks global.casa.appLoggers object {\"casaLogLevel\":\"INFO\",\"casaLogTarget\":\"STDOUT\",\"enableStdoutLogPrefix\":\"true\",\"timerLogLevel\":\"INFO\",\"timerLogTarget\":\"FILE\"} App loggers can be configured to define where the logs will be redirected to and the level of each in which it should be displayed. global.casa.appLoggers.casaLogLevel string \"INFO\" casa.log level global.casa.appLoggers.casaLogTarget string \"STDOUT\" casa.log target global.casa.appLoggers.enableStdoutLogPrefix string \"true\" Enable log prefixing which enables prepending the STDOUT logs with the file name. i.e casa ===> 2022-12-20 17:49:55,744 INFO global.casa.appLoggers.timerLogLevel string \"INFO\" casa timer log level global.casa.appLoggers.timerLogTarget string \"FILE\" casa timer log target global.casa.casaServiceName string \"casa\" Name of the casa service. Please keep it as default. global.casa.cnCustomJavaOptions string \"\" passing custom java options to casa. Notice you do not need to pass in any loggers options as they are introduced below in appLoggers. DO NOT PASS JAVA_OPTIONS in envs. global.casa.enabled bool true Boolean flag to enable/disable the casa chart. global.casa.ingress object {\"casaEnabled\":false} Enable endpoints in either istio or nginx ingress depending on users choice global.casa.ingress.casaEnabled bool false Enable casa endpoints /casa global.cloud.testEnviroment bool false Boolean flag if enabled will strip resources requests and limits from all services. global.cnCouchbasePasswordFile string \"/etc/jans/conf/couchbase_password\" Path to Couchbase password file global.cnCouchbaseSuperuserPasswordFile string \"/etc/jans/conf/couchbase_superuser_password\" Path to Couchbase superuser password file global.cnDocumentStoreType string \"DB\" Document store type to use for shibboleth files DB. global.cnGoogleApplicationCredentials string \"/etc/jans/conf/google-credentials.json\" Base64 encoded service account. The sa must have roles/secretmanager.admin to use Google secrets and roles/spanner.databaseUser to use Spanner. Leave as this is a sensible default. global.cnLdapCacertFile string \"/etc/certs/opendj.pem\" Path to OpenDJ CA cert file global.cnLdapCertFile string \"/etc/certs/opendj.crt\" Path to OpenDJ cert file global.cnLdapKeyFile string \"/etc/certs/opendj.key\" Path to OpenDJ key file global.cnLdapPasswordFile string \"/etc/jans/conf/ldap_password\" Path to LDAP password file global.cnLdapTruststoreFile string \"/etc/certs/opendj.pkcs12\" Path to OpenDJ truststore file global.cnLdapTruststorePasswordFile string \"/etc/jans/conf/ldap_truststore_password\" Path to LDAP truststore password file global.cnObExtSigningAlias string \"\" Open banking external signing AS Alias. This is a kid value.Used in SSA Validation, kid used while encoding a JWT sent to token URL i.e. XkwIzWy44xWSlcWnMiEc8iq9s2G global.cnObExtSigningJwksCrt string \"\" Open banking external signing jwks AS certificate authority string. Used in SSA Validation. This must be encoded using base64.. Used when .global.cnObExtSigningJwksUri is set. global.cnObExtSigningJwksKey string \"\" Open banking external signing jwks AS key string. Used in SSA Validation. This must be encoded using base64. Used when .global.cnObExtSigningJwksUri is set. global.cnObExtSigningJwksKeyPassPhrase string \"\" Open banking external signing jwks AS key passphrase to unlock provided key. This must be encoded using base64. Used when .global.cnObExtSigningJwksUri is set. global.cnObExtSigningJwksUri string \"\" Open banking external signing jwks uri. Used in SSA Validation. global.cnObStaticSigningKeyKid string \"\" Open banking signing AS kid to force the AS to use a specific signing key. i.e. Wy44xWSlcWnMiEc8iq9s2G global.cnObTransportAlias string \"\" Open banking transport Alias used inside the JVM. global.cnObTransportCrt string \"\" Open banking AS transport crt. Used in SSA Validation. This must be encoded using base64. global.cnObTransportKey string \"\" Open banking AS transport key. Used in SSA Validation. This must be encoded using base64. global.cnObTransportKeyPassPhrase string \"\" Open banking AS transport key passphrase to unlock AS transport key. This must be encoded using base64. global.cnObTransportTrustStore string \"\" Open banking AS transport truststore crt. This is normally generated from the OB issuing CA, OB Root CA and Signing CA. Used when .global.cnObExtSigningJwksUri is set. Used in SSA Validation. This must be encoded using base64. global.cnPersistenceType string \"sql\" Persistence backend to run Gluu with ldap global.cnPrometheusPort string \"\" Port used by Prometheus JMX agent (default to empty string). To enable Prometheus JMX agent, set the value to a number. global.cnSqlPasswordFile string \"/etc/jans/conf/sql_password\" Path to SQL password file global.config-api.adminUiAppLoggers.adminUiAuditLogLevel string \"INFO\" config-api admin-ui plugin audit log level global.config-api.adminUiAppLoggers.adminUiAuditLogTarget string \"FILE\" config-api admin-ui plugin audit log target global.config-api.adminUiAppLoggers.adminUiLogLevel string \"INFO\" config-api admin-ui plugin log target global.config-api.adminUiAppLoggers.adminUiLogTarget string \"FILE\" config-api admin-ui plugin log level global.config-api.adminUiAppLoggers.enableStdoutLogPrefix string \"true\" Enable log prefixing which enables prepending the STDOUT logs with the file name. i.e config-api_persistence ===> 2022-12-20 17:49:55,744 INFO global.config-api.appLoggers object {\"configApiLogLevel\":\"INFO\",\"configApiLogTarget\":\"STDOUT\",\"enableStdoutLogPrefix\":\"true\",\"ldapStatsLogLevel\":\"INFO\",\"ldapStatsLogTarget\":\"FILE\",\"persistenceDurationLogLevel\":\"INFO\",\"persistenceDurationLogTarget\":\"FILE\",\"persistenceLogLevel\":\"INFO\",\"persistenceLogTarget\":\"FILE\",\"scriptLogLevel\":\"INFO\",\"scriptLogTarget\":\"FILE\"} App loggers can be configured to define where the logs will be redirected to and the level of each in which it should be displayed. global.config-api.appLoggers.configApiLogLevel string \"INFO\" configapi.log level global.config-api.appLoggers.configApiLogTarget string \"STDOUT\" configapi.log target global.config-api.appLoggers.enableStdoutLogPrefix string \"true\" Enable log prefixing which enables prepending the STDOUT logs with the file name. i.e config-api_persistence ===> 2022-12-20 17:49:55,744 INFO global.config-api.appLoggers.ldapStatsLogLevel string \"INFO\" config-api_persistence_ldap_statistics.log level global.config-api.appLoggers.ldapStatsLogTarget string \"FILE\" config-api_persistence_ldap_statistics.log target global.config-api.appLoggers.persistenceDurationLogLevel string \"INFO\" config-api_persistence_duration.log level global.config-api.appLoggers.persistenceDurationLogTarget string \"FILE\" config-api_persistence_duration.log target global.config-api.appLoggers.persistenceLogLevel string \"INFO\" config-api_persistence.log level global.config-api.appLoggers.persistenceLogTarget string \"FILE\" config-api_persistence.log target global.config-api.appLoggers.scriptLogLevel string \"INFO\" config-api_script.log level global.config-api.appLoggers.scriptLogTarget string \"FILE\" config-api_script.log target global.config-api.cnCustomJavaOptions string \"\" passing custom java options to config-api. Notice you do not need to pass in any loggers options as they are introduced below in appLoggers. DO NOT PASS JAVA_OPTIONS in envs. global.config-api.configApiServerServiceName string \"config-api\" Name of the config-api service. Please keep it as default. global.config-api.enabled bool true Boolean flag to enable/disable the config-api chart. global.config-api.ingress object {\"configApiEnabled\":true} Enable endpoints in either istio or nginx ingress depending on users choice global.config-api.plugins string \"admin-ui,fido2,scim,user-mgt\" Comma-separated values of enabled plugins (supported plugins are \"admin-ui\",\"fido2\",\"scim\",\"user-mgt\",\"jans-link\",\"kc-saml\") global.config.enabled bool true Boolean flag to enable/disable the configuration chart. This normally should never be false global.configAdapterName string \"kubernetes\" The config backend adapter that will hold Gluu configuration layer. aws global.configSecretAdapter string \"kubernetes\" The config backend adapter that will hold Gluu secret layer. vault global.distribution string \"default\" Gluu distributions supported are: default global.fido2.appLoggers object {\"enableStdoutLogPrefix\":\"true\",\"fido2LogLevel\":\"INFO\",\"fido2LogTarget\":\"STDOUT\",\"persistenceDurationLogLevel\":\"INFO\",\"persistenceDurationLogTarget\":\"FILE\",\"persistenceLogLevel\":\"INFO\",\"persistenceLogTarget\":\"FILE\",\"scriptLogLevel\":\"INFO\",\"scriptLogTarget\":\"FILE\"} App loggers can be configured to define where the logs will be redirected to and the level of each in which it should be displayed. global.fido2.appLoggers.enableStdoutLogPrefix string \"true\" Enable log prefixing which enables prepending the STDOUT logs with the file name. i.e fido2 ===> 2022-12-20 17:49:55,744 INFO global.fido2.appLoggers.fido2LogLevel string \"INFO\" fido2.log level global.fido2.appLoggers.fido2LogTarget string \"STDOUT\" fido2.log target global.fido2.appLoggers.persistenceDurationLogLevel string \"INFO\" fido2_persistence_duration.log level global.fido2.appLoggers.persistenceDurationLogTarget string \"FILE\" fido2_persistence_duration.log target global.fido2.appLoggers.persistenceLogLevel string \"INFO\" fido2_persistence.log level global.fido2.appLoggers.persistenceLogTarget string \"FILE\" fido2_persistence.log target global.fido2.appLoggers.scriptLogLevel string \"INFO\" fido2_script.log level global.fido2.appLoggers.scriptLogTarget string \"FILE\" fido2_script.log target global.fido2.cnCustomJavaOptions string \"\" passing custom java options to fido2. Notice you do not need to pass in any loggers options as they are introduced below in appLoggers. DO NOT PASS JAVA_OPTIONS in envs. global.fido2.enabled bool true Boolean flag to enable/disable the fido2 chart. global.fido2.fido2ServiceName string \"fido2\" Name of the fido2 service. Please keep it as default. global.fido2.ingress object {\"fido2ConfigEnabled\":false,\"fido2Enabled\":false} Enable endpoints in either istio or nginx ingress depending on users choice global.fido2.ingress.fido2ConfigEnabled bool false Enable endpoint /.well-known/fido2-configuration global.fido2.ingress.fido2Enabled bool false Enable endpoint /jans-fido2 global.fqdn string \"demoexample.gluu.org\" Fully qualified domain name to be used for Gluu installation. This address will be used to reach Gluu services. global.gcePdStorageType string \"pd-standard\" GCE storage kind if using Google disks global.isFqdnRegistered bool false Boolean flag to enable mapping global.lbIp to global.fqdn inside pods on clouds that provide static ip for load balancers. On cloud that provide only addresses to the LB this flag will enable a script to actively scan config.configmap.lbAddr and update the hosts file inside the pods automatically. global.istio.additionalAnnotations object {} Additional annotations that will be added across the gateway in the format of global.istio.additionalLabels object {} Additional labels that will be added across the gateway in the format of global.istio.enabled bool false Boolean flag that enables using istio side-cars with Gluu services. global.istio.gateways list [] Override the gateway that can be created by default. This is used when istio ingress has already been setup and the gateway exists. global.istio.ingress bool false Boolean flag that enables using istio gateway for Gluu. This assumes istio ingress is installed and hence the LB is available. global.istio.namespace string \"istio-system\" The namespace istio is deployed in. The is normally istio-system. global.jobTtlSecondsAfterFinished int 300 https://kubernetes.io/docs/concepts/workloads/controllers/ttlafterfinished/ global.kc-scheduler.enabled bool false Boolean flag to enable/disable the kc-scheduler cronjob chart. global.kcAdminCredentialsFile string \"/etc/jans/conf/kc_admin_creds\" Path to file contains Keycloak admin credentials (username and password) global.kcDbPasswordFile string \"/etc/jans/conf/kc_db_password\" Path to file contains password for database access global.lbIp string \"22.22.22.22\" The Loadbalancer IP created by nginx or istio on clouds that provide static IPs. This is not needed if global.fqdn is globally resolvable. global.link.appLoggers object {\"enableStdoutLogPrefix\":\"true\",\"ldapStatsLogLevel\":\"INFO\",\"ldapStatsLogTarget\":\"FILE\",\"linkLogLevel\":\"INFO\",\"linkLogTarget\":\"STDOUT\",\"persistenceDurationLogLevel\":\"INFO\",\"persistenceDurationLogTarget\":\"FILE\",\"persistenceLogLevel\":\"INFO\",\"persistenceLogTarget\":\"FILE\",\"scriptLogLevel\":\"INFO\",\"scriptLogTarget\":\"FILE\"} App loggers can be configured to define where the logs will be redirected to and the level of each in which it should be displayed. global.link.appLoggers.enableStdoutLogPrefix string \"true\" Enable log prefixing which enables prepending the STDOUT logs with the file name. i.e link-persistence ===> 2022-12-20 17:49:55,744 INFO global.link.appLoggers.ldapStatsLogLevel string \"INFO\" cacherefresh_persistence_ldap_statistics.log level global.link.appLoggers.ldapStatsLogTarget string \"FILE\" cacherefresh_persistence_ldap_statistics.log target global.link.appLoggers.linkLogLevel string \"INFO\" cacherefresh.log level global.link.appLoggers.linkLogTarget string \"STDOUT\" cacherefresh.log target global.link.appLoggers.persistenceDurationLogLevel string \"INFO\" cacherefresh_persistence_duration.log level global.link.appLoggers.persistenceDurationLogTarget string \"FILE\" cacherefresh_persistence_duration.log target global.link.appLoggers.persistenceLogLevel string \"INFO\" cacherefresh_persistence.log level global.link.appLoggers.persistenceLogTarget string \"FILE\" cacherefresh_persistence.log target global.link.appLoggers.scriptLogLevel string \"INFO\" cacherefresh_script.log level global.link.appLoggers.scriptLogTarget string \"FILE\" cacherefresh_script.log target global.link.cnCustomJavaOptions string \"\" passing custom java options to link. Notice you do not need to pass in any loggers options as they are introduced below in appLoggers. DO NOT PASS JAVA_OPTIONS in envs. global.link.enabled bool false Boolean flag to enable/disable the link chart. global.link.ingress object {\"linkEnabled\":true} Enable endpoints in either istio or nginx ingress depending on users choice global.link.linkServiceName string \"link\" Name of the link service. Please keep it as default. global.nginx-ingress.enabled bool true Boolean flag to enable/disable the nginx-ingress definitions chart. global.opendj.enabled bool false Boolean flag to enable/disable the OpenDJ chart. global.opendj.ldapServiceName string \"opendj\" Name of the OpenDJ service. Please keep it as default. global.persistence.enabled bool true Boolean flag to enable/disable the persistence chart. global.saml.cnCustomJavaOptions string \"\" passing custom java options to saml. DO NOT PASS JAVA_OPTIONS in envs. global.saml.enabled bool false Boolean flag to enable/disable the saml chart. global.saml.ingress object {\"samlEnabled\":false} Enable endpoints in either istio or nginx ingress depending on users choice global.saml.samlServiceName string \"saml\" Name of the saml service. Please keep it as default. global.scim.appLoggers object {\"enableStdoutLogPrefix\":\"true\",\"ldapStatsLogLevel\":\"INFO\",\"ldapStatsLogTarget\":\"FILE\",\"persistenceDurationLogLevel\":\"INFO\",\"persistenceDurationLogTarget\":\"FILE\",\"persistenceLogLevel\":\"INFO\",\"persistenceLogTarget\":\"FILE\",\"scimLogLevel\":\"INFO\",\"scimLogTarget\":\"STDOUT\",\"scriptLogLevel\":\"INFO\",\"scriptLogTarget\":\"FILE\"} App loggers can be configured to define where the logs will be redirected to and the level of each in which it should be displayed. global.scim.appLoggers.enableStdoutLogPrefix string \"true\" Enable log prefixing which enables prepending the STDOUT logs with the file name. i.e jans-scim ===> 2022-12-20 17:49:55,744 INFO global.scim.appLoggers.ldapStatsLogLevel string \"INFO\" jans-scim_persistence_ldap_statistics.log level global.scim.appLoggers.ldapStatsLogTarget string \"FILE\" jans-scim_persistence_ldap_statistics.log target global.scim.appLoggers.persistenceDurationLogLevel string \"INFO\" jans-scim_persistence_duration.log level global.scim.appLoggers.persistenceDurationLogTarget string \"FILE\" jans-scim_persistence_duration.log target global.scim.appLoggers.persistenceLogLevel string \"INFO\" jans-scim_persistence.log level global.scim.appLoggers.persistenceLogTarget string \"FILE\" jans-scim_persistence.log target global.scim.appLoggers.scimLogLevel string \"INFO\" jans-scim.log level global.scim.appLoggers.scimLogTarget string \"STDOUT\" jans-scim.log target global.scim.appLoggers.scriptLogLevel string \"INFO\" jans-scim_script.log level global.scim.appLoggers.scriptLogTarget string \"FILE\" jans-scim_script.log target global.scim.cnCustomJavaOptions string \"\" passing custom java options to scim. Notice you do not need to pass in any loggers options as they are introduced below in appLoggers. DO NOT PASS JAVA_OPTIONS in envs. global.scim.enabled bool true Boolean flag to enable/disable the SCIM chart. global.scim.ingress object {\"scimConfigEnabled\":false,\"scimEnabled\":false} Enable endpoints in either istio or nginx ingress depending on users choice global.scim.ingress.scimConfigEnabled bool false Enable endpoint /.well-known/scim-configuration global.scim.ingress.scimEnabled bool false Enable SCIM endpoints /jans-scim global.scim.scimServiceName string \"scim\" Name of the scim service. Please keep it as default. global.storageClass object {\"allowVolumeExpansion\":true,\"allowedTopologies\":[],\"mountOptions\":[\"debug\"],\"parameters\":{},\"provisioner\":\"microk8s.io/hostpath\",\"reclaimPolicy\":\"Retain\",\"volumeBindingMode\":\"WaitForFirstConsumer\"} StorageClass section for OpenDJ charts. This is not currently used by the openbanking distribution. You may specify custom parameters as needed. global.storageClass.parameters object {} parameters: fsType: \"\" kind: \"\" pool: \"\" storageAccountType: \"\" type: \"\" global.usrEnvs object {\"normal\":{},\"secret\":{}} Add custom normal and secret envs to the service. Envs defined in global.userEnvs will be globally available to all services global.usrEnvs.normal object {} Add custom normal envs to the service. variable1: value1 global.usrEnvs.secret object {} Add custom secret envs to the service. variable1: value1 installer-settings object {\"acceptLicense\":\"\",\"aws\":{\"arn\":{\"arnAcmCert\":\"\",\"enabled\":\"\"},\"lbType\":\"\",\"vpcCidr\":\"0.0.0.0/0\"},\"confirmSettings\":false,\"couchbase\":{\"backup\":{\"fullSchedule\":\"\",\"incrementalSchedule\":\"\",\"retentionTime\":\"\",\"storageSize\":\"\"},\"clusterName\":\"\",\"commonName\":\"\",\"customFileOverride\":\"\",\"install\":\"\",\"lowResourceInstall\":\"\",\"namespace\":\"\",\"subjectAlternativeName\":\"\",\"totalNumberOfExpectedTransactionsPerSec\":\"\",\"totalNumberOfExpectedUsers\":\"\",\"volumeType\":\"\"},\"currentVersion\":\"\",\"google\":{\"useSecretManager\":\"\"},\"images\":{\"edit\":\"\"},\"ldap\":{\"backup\":{\"fullSchedule\":\"\"}},\"namespace\":\"\",\"nginxIngress\":{\"namespace\":\"\",\"releaseName\":\"\"},\"nodes\":{\"ips\":\"\",\"names\":\"\",\"zones\":\"\"},\"openbanking\":{\"cnObTransportTrustStoreP12password\":\"\",\"hasCnObTransportTrustStore\":false},\"postgres\":{\"install\":\"\",\"namespace\":\"\"},\"redis\":{\"install\":\"\",\"namespace\":\"\"},\"releaseName\":\"\",\"sql\":{\"install\":\"\",\"namespace\":\"\"},\"volumeProvisionStrategy\":\"\"} Only used by the installer. These settings do not affect nor are used by the chart kc-scheduler object {\"additionalAnnotations\":{},\"additionalLabels\":{},\"customScripts\":[],\"dnsConfig\":{},\"dnsPolicy\":\"\",\"image\":{\"pullPolicy\":\"IfNotPresent\",\"pullSecrets\":[],\"repository\":\"ghcr.io/janssenproject/jans/kc-scheduler\",\"tag\":\"1.1.6_dev\"},\"interval\":10,\"lifecycle\":{},\"resources\":{\"limits\":{\"cpu\":\"300m\",\"memory\":\"300Mi\"},\"requests\":{\"cpu\":\"300m\",\"memory\":\"300Mi\"}},\"usrEnvs\":{\"normal\":{},\"secret\":{}},\"volumeMounts\":[],\"volumes\":[]} Responsible for synchronizing Keycloak SAML clients kc-scheduler.additionalAnnotations object {} Additional annotations that will be added across the gateway in the format of kc-scheduler.additionalLabels object {} Additional labels that will be added across the gateway in the format of kc-scheduler.customScripts list [] Add custom scripts that have been mounted to run before the entrypoint. - /tmp/custom.sh - /tmp/custom2.sh kc-scheduler.dnsConfig object {} Add custom dns config kc-scheduler.dnsPolicy string \"\" Add custom dns policy kc-scheduler.image.pullPolicy string \"IfNotPresent\" Image pullPolicy to use for deploying. kc-scheduler.image.pullSecrets list [] Image Pull Secrets kc-scheduler.image.repository string \"ghcr.io/janssenproject/jans/kc-scheduler\" Image to use for deploying. kc-scheduler.image.tag string \"1.1.6_dev\" Image tag to use for deploying. kc-scheduler.interval int 10 Interval of running the scheduler (in minutes) kc-scheduler.resources object {\"limits\":{\"cpu\":\"300m\",\"memory\":\"300Mi\"},\"requests\":{\"cpu\":\"300m\",\"memory\":\"300Mi\"}} Resource specs. kc-scheduler.resources.limits.cpu string \"300m\" CPU limit. kc-scheduler.resources.limits.memory string \"300Mi\" Memory limit. kc-scheduler.resources.requests.cpu string \"300m\" CPU request. kc-scheduler.resources.requests.memory string \"300Mi\" Memory request. kc-scheduler.usrEnvs object {\"normal\":{},\"secret\":{}} Add custom normal and secret envs to the service kc-scheduler.usrEnvs.normal object {} Add custom normal envs to the service variable1: value1 kc-scheduler.usrEnvs.secret object {} Add custom secret envs to the service variable1: value1 kc-scheduler.volumeMounts list [] Configure any additional volumesMounts that need to be attached to the containers kc-scheduler.volumes list [] Configure any additional volumes that need to be attached to the pod link object {\"additionalAnnotations\":{},\"additionalLabels\":{},\"customScripts\":[],\"dnsConfig\":{},\"dnsPolicy\":\"\",\"hpa\":{\"behavior\":{},\"enabled\":true,\"maxReplicas\":10,\"metrics\":[],\"minReplicas\":1,\"targetCPUUtilizationPercentage\":50},\"image\":{\"pullPolicy\":\"IfNotPresent\",\"pullSecrets\":[],\"repository\":\"ghcr.io/janssenproject/jans/link\",\"tag\":\"1.1.6_dev\"},\"lifecycle\":{},\"livenessProbe\":{\"exec\":{\"command\":[\"python3\",\"/app/scripts/healthcheck.py\"]},\"initialDelaySeconds\":30,\"periodSeconds\":30,\"timeoutSeconds\":5},\"pdb\":{\"enabled\":true,\"maxUnavailable\":\"90%\"},\"readinessProbe\":{\"exec\":{\"command\":[\"python3\",\"/app/scripts/healthcheck.py\"]},\"initialDelaySeconds\":25,\"periodSeconds\":25,\"timeoutSeconds\":5},\"replicas\":1,\"resources\":{\"limits\":{\"cpu\":\"500m\",\"memory\":\"1200Mi\"},\"requests\":{\"cpu\":\"500m\",\"memory\":\"1200Mi\"}},\"topologySpreadConstraints\":{},\"usrEnvs\":{\"normal\":{},\"secret\":{}},\"volumeMounts\":[],\"volumes\":[]} Link. link.additionalAnnotations object {} Additional annotations that will be added across the gateway in the format of link.additionalLabels object {} Additional labels that will be added across the gateway in the format of link.customScripts list [] Add custom scripts that have been mounted to run before the entrypoint. - /tmp/custom.sh - /tmp/custom2.sh link.dnsConfig object {} Add custom dns config link.dnsPolicy string \"\" Add custom dns policy link.hpa object {\"behavior\":{},\"enabled\":true,\"maxReplicas\":10,\"metrics\":[],\"minReplicas\":1,\"targetCPUUtilizationPercentage\":50} Configure the HorizontalPodAutoscaler link.hpa.behavior object {} Scaling Policies link.hpa.metrics list [] metrics if targetCPUUtilizationPercentage is not set link.image.pullPolicy string \"IfNotPresent\" Image pullPolicy to use for deploying. link.image.pullSecrets list [] Image Pull Secrets link.image.repository string \"ghcr.io/janssenproject/jans/link\" Image to use for deploying. link.image.tag string \"1.1.6_dev\" Image tag to use for deploying. link.livenessProbe object {\"exec\":{\"command\":[\"python3\",\"/app/scripts/healthcheck.py\"]},\"initialDelaySeconds\":30,\"periodSeconds\":30,\"timeoutSeconds\":5} Configure the liveness healthcheck for the auth server if needed. link.livenessProbe.exec object {\"command\":[\"python3\",\"/app/scripts/healthcheck.py\"]} http liveness probe endpoint link.pdb object {\"enabled\":true,\"maxUnavailable\":\"90%\"} Configure the PodDisruptionBudget link.readinessProbe.exec object {\"command\":[\"python3\",\"/app/scripts/healthcheck.py\"]} http readiness probe endpoint link.replicas int 1 Service replica number. link.resources object {\"limits\":{\"cpu\":\"500m\",\"memory\":\"1200Mi\"},\"requests\":{\"cpu\":\"500m\",\"memory\":\"1200Mi\"}} Resource specs. link.resources.limits.cpu string \"500m\" CPU limit. link.resources.limits.memory string \"1200Mi\" Memory limit. This value is used to calculate memory allocation for Java. Currently it only supports Mi . Please refrain from using other units. link.resources.requests.cpu string \"500m\" CPU request. link.resources.requests.memory string \"1200Mi\" Memory request. link.topologySpreadConstraints object {} Configure the topology spread constraints. Notice this is a map NOT a list as in the upstream API https://kubernetes.io/docs/concepts/scheduling-eviction/topology-spread-constraints/ link.usrEnvs object {\"normal\":{},\"secret\":{}} Add custom normal and secret envs to the service link.usrEnvs.normal object {} Add custom normal envs to the service variable1: value1 link.usrEnvs.secret object {} Add custom secret envs to the service variable1: value1 link.volumeMounts list [] Configure any additional volumesMounts that need to be attached to the containers link.volumes list [] Configure any additional volumes that need to be attached to the pod nginx-ingress object {\"certManager\":{\"certificate\":{\"enabled\":false,\"issuerGroup\":\"cert-manager.io\",\"issuerKind\":\"ClusterIssuer\",\"issuerName\":\"\"}},\"ingress\":{\"additionalAnnotations\":{},\"additionalLabels\":{},\"adminUiAdditionalAnnotations\":{},\"adminUiLabels\":{},\"authServerAdditionalAnnotations\":{},\"authServerLabels\":{},\"authServerProtectedRegisterAdditionalAnnotations\":{},\"authServerProtectedRegisterLabels\":{},\"authServerProtectedTokenAdditionalAnnotations\":{},\"authServerProtectedTokenLabels\":{},\"casaAdditionalAnnotations\":{},\"casaLabels\":{},\"configApiAdditionalAnnotations\":{},\"configApiLabels\":{},\"deviceCodeAdditionalAnnotations\":{},\"deviceCodeLabels\":{},\"fido2AdditionalAnnotations\":{},\"fido2ConfigAdditionalAnnotations\":{},\"fido2ConfigLabels\":{},\"fido2Labels\":{},\"firebaseMessagingAdditionalAnnotations\":{},\"firebaseMessagingLabels\":{},\"hosts\":[\"demoexample.gluu.org\"],\"ingressClassName\":\"nginx\",\"openidAdditionalAnnotations\":{},\"openidConfigLabels\":{},\"path\":\"/\",\"samlAdditionalAnnotations\":{},\"samlLabels\":{},\"scimAdditionalAnnotations\":{},\"scimConfigAdditionalAnnotations\":{},\"scimConfigLabels\":{},\"scimLabels\":{},\"tls\":[{\"hosts\":[\"demoexample.gluu.org\"],\"secretName\":\"tls-certificate\"}],\"u2fAdditionalAnnotations\":{},\"u2fConfigLabels\":{},\"uma2AdditionalAnnotations\":{},\"uma2ConfigLabels\":{},\"webdiscoveryAdditionalAnnotations\":{},\"webdiscoveryLabels\":{},\"webfingerAdditionalAnnotations\":{},\"webfingerLabels\":{}}} Nginx ingress definitions chart nginx-ingress.ingress.additionalAnnotations object {} Additional annotations that will be added across all ingress definitions in the format of {cert-manager.io/issuer: \"letsencrypt-prod\"} Enable client certificate authentication nginx.ingress.kubernetes.io/auth-tls-verify-client: \"optional\" Create the secret containing the trusted ca certificates nginx.ingress.kubernetes.io/auth-tls-secret: \"gluu/tls-certificate\" Specify the verification depth in the client certificates chain nginx.ingress.kubernetes.io/auth-tls-verify-depth: \"1\" Specify if certificates are passed to upstream server nginx.ingress.kubernetes.io/auth-tls-pass-certificate-to-upstream: \"true\" nginx-ingress.ingress.additionalLabels object {} Additional labels that will be added across all ingress definitions in the format of nginx-ingress.ingress.adminUiAdditionalAnnotations object {} openid-configuration ingress resource additional annotations. nginx-ingress.ingress.adminUiLabels object {} Admin UI ingress resource labels. key app is taken. nginx-ingress.ingress.authServerAdditionalAnnotations object {} Auth server ingress resource additional annotations. nginx-ingress.ingress.authServerLabels object {} Auth server ingress resource labels. key app is taken nginx-ingress.ingress.authServerProtectedRegisterAdditionalAnnotations object {} Auth server protected register ingress resource additional annotations. nginx-ingress.ingress.authServerProtectedRegisterLabels object {} Auth server protected token ingress resource labels. key app is taken nginx-ingress.ingress.authServerProtectedTokenAdditionalAnnotations object {} Auth server protected token ingress resource additional annotations. nginx-ingress.ingress.authServerProtectedTokenLabels object {} Auth server protected token ingress resource labels. key app is taken nginx-ingress.ingress.casaAdditionalAnnotations object {} Casa ingress resource additional annotations. nginx-ingress.ingress.casaLabels object {} Casa ingress resource labels. key app is taken nginx-ingress.ingress.configApiAdditionalAnnotations object {} ConfigAPI ingress resource additional annotations. nginx-ingress.ingress.configApiLabels object {} configAPI ingress resource labels. key app is taken nginx-ingress.ingress.deviceCodeAdditionalAnnotations object {} device-code ingress resource additional annotations. nginx-ingress.ingress.deviceCodeLabels object {} device-code ingress resource labels. key app is taken nginx-ingress.ingress.fido2AdditionalAnnotations object {} fido2 ingress resource additional annotations. nginx-ingress.ingress.fido2ConfigAdditionalAnnotations object {} fido2 config ingress resource additional annotations. nginx-ingress.ingress.fido2ConfigLabels object {} fido2 config ingress resource labels. key app is taken nginx-ingress.ingress.fido2Labels object {} fido2 ingress resource labels. key app is taken nginx-ingress.ingress.firebaseMessagingAdditionalAnnotations object {} Firebase Messaging ingress resource additional annotations. nginx-ingress.ingress.firebaseMessagingLabels object {} Firebase Messaging ingress resource labels. key app is taken nginx-ingress.ingress.openidAdditionalAnnotations object {} openid-configuration ingress resource additional annotations. nginx-ingress.ingress.openidConfigLabels object {} openid-configuration ingress resource labels. key app is taken nginx-ingress.ingress.samlAdditionalAnnotations object {} SAML ingress resource additional annotations. nginx-ingress.ingress.samlLabels object {} SAML config ingress resource labels. key app is taken nginx-ingress.ingress.scimAdditionalAnnotations object {} SCIM ingress resource additional annotations. nginx-ingress.ingress.scimConfigAdditionalAnnotations object {} SCIM config ingress resource additional annotations. nginx-ingress.ingress.scimConfigLabels object {} SCIM config ingress resource labels. key app is taken nginx-ingress.ingress.scimLabels object {} SCIM config ingress resource labels. key app is taken nginx-ingress.ingress.tls list [{\"hosts\":[\"demoexample.gluu.org\"],\"secretName\":\"tls-certificate\"}] Secrets holding HTTPS CA cert and key. nginx-ingress.ingress.u2fAdditionalAnnotations object {} u2f config ingress resource additional annotations. nginx-ingress.ingress.u2fConfigLabels object {} u2f config ingress resource labels. key app is taken nginx-ingress.ingress.uma2AdditionalAnnotations object {} uma2 config ingress resource additional annotations. nginx-ingress.ingress.uma2ConfigLabels object {} uma2 config ingress resource labels. key app is taken nginx-ingress.ingress.webdiscoveryAdditionalAnnotations object {} webdiscovery ingress resource additional annotations. nginx-ingress.ingress.webdiscoveryLabels object {} webdiscovery ingress resource labels. key app is taken nginx-ingress.ingress.webfingerAdditionalAnnotations object {} webfinger ingress resource additional annotations. nginx-ingress.ingress.webfingerLabels object {} webfinger ingress resource labels. key app is taken opendj object {\"additionalAnnotations\":{},\"additionalLabels\":{},\"backup\":{\"cronJobSchedule\":\"*/59 * * * *\",\"enabled\":true},\"customScripts\":[],\"dnsConfig\":{},\"dnsPolicy\":\"\",\"hpa\":{\"behavior\":{},\"enabled\":true,\"maxReplicas\":10,\"metrics\":[],\"minReplicas\":1,\"targetCPUUtilizationPercentage\":50},\"image\":{\"pullPolicy\":\"IfNotPresent\",\"pullSecrets\":[],\"repository\":\"gluufederation/opendj\",\"tag\":\"5.0.0_dev\"},\"lifecycle\":{\"preStop\":{\"exec\":{\"command\":[\"/bin/sh\",\"-c\",\"python3 /app/scripts/deregister_peer.py 1>&/proc/1/fd/1\"]}}},\"livenessProbe\":{\"exec\":{\"command\":[\"python3\",\"/app/scripts/healthcheck.py\"]},\"failureThreshold\":20,\"initialDelaySeconds\":30,\"periodSeconds\":30,\"timeoutSeconds\":5},\"pdb\":{\"enabled\":true,\"maxUnavailable\":1},\"persistence\":{\"size\":\"5Gi\"},\"ports\":{\"tcp-admin\":{\"nodePort\":\"\",\"port\":4444,\"protocol\":\"TCP\",\"targetPort\":4444},\"tcp-ldap\":{\"nodePort\":\"\",\"port\":1389,\"protocol\":\"TCP\",\"targetPort\":1389},\"tcp-ldaps\":{\"nodePort\":\"\",\"port\":1636,\"protocol\":\"TCP\",\"targetPort\":1636},\"tcp-repl\":{\"nodePort\":\"\",\"port\":8989,\"protocol\":\"TCP\",\"targetPort\":8989},\"tcp-serf\":{\"nodePort\":\"\",\"port\":7946,\"protocol\":\"TCP\",\"targetPort\":7946},\"udp-serf\":{\"nodePort\":\"\",\"port\":7946,\"protocol\":\"UDP\",\"targetPort\":7946}},\"readinessProbe\":{\"failureThreshold\":20,\"initialDelaySeconds\":60,\"periodSeconds\":25,\"tcpSocket\":{\"port\":1636},\"timeoutSeconds\":5},\"replicas\":1,\"resources\":{\"limits\":{\"cpu\":\"1500m\",\"memory\":\"2000Mi\"},\"requests\":{\"cpu\":\"1500m\",\"memory\":\"2000Mi\"}},\"topologySpreadConstraints\":{},\"usrEnvs\":{\"normal\":{},\"secret\":{}},\"volumeMounts\":[],\"volumes\":[]} OpenDJ is a directory server which implements a wide range of Lightweight Directory Access Protocol and related standards, including full compliance with LDAPv3 but also support for Directory Service Markup Language (DSMLv2).Written in Java, OpenDJ offers multi-master replication, access control, and many extensions. opendj.additionalAnnotations object {} Additional annotations that will be added across the gateway in the format of opendj.additionalLabels object {} Additional labels that will be added across the gateway in the format of opendj.backup object {\"cronJobSchedule\":\"*/59 * * * *\",\"enabled\":true} Configure ldap backup cronjob opendj.customScripts list [] Add custom scripts that have been mounted to run before the entrypoint. - /tmp/custom.sh - /tmp/custom2.sh opendj.dnsConfig object {} Add custom dns config opendj.dnsPolicy string \"\" Add custom dns policy opendj.hpa object {\"behavior\":{},\"enabled\":true,\"maxReplicas\":10,\"metrics\":[],\"minReplicas\":1,\"targetCPUUtilizationPercentage\":50} Configure the HorizontalPodAutoscaler opendj.hpa.behavior object {} Scaling Policies opendj.hpa.metrics list [] metrics if targetCPUUtilizationPercentage is not set opendj.image.pullPolicy string \"IfNotPresent\" Image pullPolicy to use for deploying. opendj.image.pullSecrets list [] Image Pull Secrets opendj.image.repository string \"gluufederation/opendj\" Image to use for deploying. opendj.image.tag string \"5.0.0_dev\" Image tag to use for deploying. opendj.livenessProbe object {\"exec\":{\"command\":[\"python3\",\"/app/scripts/healthcheck.py\"]},\"failureThreshold\":20,\"initialDelaySeconds\":30,\"periodSeconds\":30,\"timeoutSeconds\":5} Configure the liveness healthcheck for OpenDJ if needed. https://github.com/GluuFederation/docker-opendj/blob/master/scripts/healthcheck.py opendj.livenessProbe.exec object {\"command\":[\"python3\",\"/app/scripts/healthcheck.py\"]} Executes the python3 healthcheck. opendj.pdb object {\"enabled\":true,\"maxUnavailable\":1} Configure the PodDisruptionBudget opendj.persistence.size string \"5Gi\" OpenDJ volume size opendj.readinessProbe object {\"failureThreshold\":20,\"initialDelaySeconds\":60,\"periodSeconds\":25,\"tcpSocket\":{\"port\":1636},\"timeoutSeconds\":5} Configure the readiness healthcheck for OpenDJ if needed. https://github.com/GluuFederation/docker-opendj/blob/master/scripts/healthcheck.py opendj.replicas int 1 Service replica number. opendj.resources object {\"limits\":{\"cpu\":\"1500m\",\"memory\":\"2000Mi\"},\"requests\":{\"cpu\":\"1500m\",\"memory\":\"2000Mi\"}} Resource specs. opendj.resources.limits.cpu string \"1500m\" CPU limit. opendj.resources.limits.memory string \"2000Mi\" Memory limit. opendj.resources.requests.cpu string \"1500m\" CPU request. opendj.resources.requests.memory string \"2000Mi\" Memory request. opendj.topologySpreadConstraints object {} Configure the topology spread constraints. Notice this is a map NOT a list as in the upstream API https://kubernetes.io/docs/concepts/scheduling-eviction/topology-spread-constraints/ opendj.usrEnvs object {\"normal\":{},\"secret\":{}} Add custom normal and secret envs to the service opendj.usrEnvs.normal object {} Add custom normal envs to the service variable1: value1 opendj.usrEnvs.secret object {} Add custom secret envs to the service variable1: value1 opendj.volumeMounts list [] Configure any additional volumesMounts that need to be attached to the containers opendj.volumes list [] Configure any additional volumes that need to be attached to the pod persistence object {\"additionalAnnotations\":{},\"additionalLabels\":{},\"customScripts\":[],\"dnsConfig\":{},\"dnsPolicy\":\"\",\"image\":{\"pullPolicy\":\"IfNotPresent\",\"pullSecrets\":[],\"repository\":\"ghcr.io/janssenproject/jans/persistence-loader\",\"tag\":\"1.1.6_dev\"},\"lifecycle\":{},\"resources\":{\"limits\":{\"cpu\":\"300m\",\"memory\":\"300Mi\"},\"requests\":{\"cpu\":\"300m\",\"memory\":\"300Mi\"}},\"usrEnvs\":{\"normal\":{},\"secret\":{}},\"volumeMounts\":[],\"volumes\":[]} Job to generate data and initial config for Gluu Server persistence layer. persistence.additionalAnnotations object {} Additional annotations that will be added across the gateway in the format of persistence.additionalLabels object {} Additional labels that will be added across the gateway in the format of persistence.customScripts list [] Add custom scripts that have been mounted to run before the entrypoint. - /tmp/custom.sh - /tmp/custom2.sh persistence.dnsConfig object {} Add custom dns config persistence.dnsPolicy string \"\" Add custom dns policy persistence.image.pullPolicy string \"IfNotPresent\" Image pullPolicy to use for deploying. persistence.image.pullSecrets list [] Image Pull Secrets persistence.image.repository string \"ghcr.io/janssenproject/jans/persistence-loader\" Image to use for deploying. persistence.image.tag string \"1.1.6_dev\" Image tag to use for deploying. persistence.resources object {\"limits\":{\"cpu\":\"300m\",\"memory\":\"300Mi\"},\"requests\":{\"cpu\":\"300m\",\"memory\":\"300Mi\"}} Resource specs. persistence.resources.limits.cpu string \"300m\" CPU limit persistence.resources.limits.memory string \"300Mi\" Memory limit. persistence.resources.requests.cpu string \"300m\" CPU request. persistence.resources.requests.memory string \"300Mi\" Memory request. persistence.usrEnvs object {\"normal\":{},\"secret\":{}} Add custom normal and secret envs to the service persistence.usrEnvs.normal object {} Add custom normal envs to the service variable1: value1 persistence.usrEnvs.secret object {} Add custom secret envs to the service variable1: value1 persistence.volumeMounts list [] Configure any additional volumesMounts that need to be attached to the containers persistence.volumes list [] Configure any additional volumes that need to be attached to the pod saml object {\"additionalAnnotations\":{},\"additionalLabels\":{},\"customScripts\":[],\"dnsConfig\":{},\"dnsPolicy\":\"\",\"hpa\":{\"behavior\":{},\"enabled\":true,\"maxReplicas\":10,\"metrics\":[],\"minReplicas\":1,\"targetCPUUtilizationPercentage\":50},\"image\":{\"pullPolicy\":\"IfNotPresent\",\"pullSecrets\":[],\"repository\":\"ghcr.io/janssenproject/jans/saml\",\"tag\":\"1.1.6_dev\"},\"lifecycle\":{},\"livenessProbe\":{\"exec\":{\"command\":[\"python3\",\"/app/scripts/healthcheck.py\"]},\"failureThreshold\":10,\"initialDelaySeconds\":30,\"periodSeconds\":30,\"timeoutSeconds\":5},\"pdb\":{\"enabled\":true,\"maxUnavailable\":\"90%\"},\"readinessProbe\":{\"exec\":{\"command\":[\"python3\",\"/app/scripts/healthcheck.py\"]},\"failureThreshold\":10,\"initialDelaySeconds\":25,\"periodSeconds\":25,\"timeoutSeconds\":5},\"replicas\":1,\"resources\":{\"limits\":{\"cpu\":\"500m\",\"memory\":\"1200Mi\"},\"requests\":{\"cpu\":\"500m\",\"memory\":\"1200Mi\"}},\"topologySpreadConstraints\":{},\"usrEnvs\":{\"normal\":{},\"secret\":{}},\"volumeMounts\":[],\"volumes\":[]} SAML. saml.additionalAnnotations object {} Additional annotations that will be added across the gateway in the format of saml.additionalLabels object {} Additional labels that will be added across the gateway in the format of saml.customScripts list [] Add custom scripts that have been mounted to run before the entrypoint. - /tmp/custom.sh - /tmp/custom2.sh saml.dnsConfig object {} Add custom dns config saml.dnsPolicy string \"\" Add custom dns policy saml.hpa object {\"behavior\":{},\"enabled\":true,\"maxReplicas\":10,\"metrics\":[],\"minReplicas\":1,\"targetCPUUtilizationPercentage\":50} Configure the HorizontalPodAutoscaler saml.hpa.behavior object {} Scaling Policies saml.hpa.metrics list [] metrics if targetCPUUtilizationPercentage is not set saml.image.pullPolicy string \"IfNotPresent\" Image pullPolicy to use for deploying. saml.image.pullSecrets list [] Image Pull Secrets saml.image.repository string \"ghcr.io/janssenproject/jans/saml\" Image to use for deploying. saml.image.tag string \"1.1.6_dev\" Image tag to use for deploying. saml.livenessProbe object {\"exec\":{\"command\":[\"python3\",\"/app/scripts/healthcheck.py\"]},\"failureThreshold\":10,\"initialDelaySeconds\":30,\"periodSeconds\":30,\"timeoutSeconds\":5} Configure the liveness healthcheck for the auth server if needed. saml.livenessProbe.exec object {\"command\":[\"python3\",\"/app/scripts/healthcheck.py\"]} http liveness probe endpoint saml.pdb object {\"enabled\":true,\"maxUnavailable\":\"90%\"} Configure the PodDisruptionBudget saml.readinessProbe.exec object {\"command\":[\"python3\",\"/app/scripts/healthcheck.py\"]} http readiness probe endpoint saml.replicas int 1 Service replica number. saml.resources object {\"limits\":{\"cpu\":\"500m\",\"memory\":\"1200Mi\"},\"requests\":{\"cpu\":\"500m\",\"memory\":\"1200Mi\"}} Resource specs. saml.resources.limits.cpu string \"500m\" CPU limit. saml.resources.limits.memory string \"1200Mi\" Memory limit. This value is used to calculate memory allocation for Java. Currently it only supports Mi . Please refrain from using other units. saml.resources.requests.cpu string \"500m\" CPU request. saml.resources.requests.memory string \"1200Mi\" Memory request. saml.topologySpreadConstraints object {} Configure the topology spread constraints. Notice this is a map NOT a list as in the upstream API https://kubernetes.io/docs/concepts/scheduling-eviction/topology-spread-constraints/ saml.usrEnvs object {\"normal\":{},\"secret\":{}} Add custom normal and secret envs to the service saml.usrEnvs.normal object {} Add custom normal envs to the service variable1: value1 saml.usrEnvs.secret object {} Add custom secret envs to the service variable1: value1 saml.volumeMounts list [] Configure any additional volumesMounts that need to be attached to the containers saml.volumes list [] Configure any additional volumes that need to be attached to the pod scim object {\"additionalAnnotations\":{},\"additionalLabels\":{},\"customScripts\":[],\"dnsConfig\":{},\"dnsPolicy\":\"\",\"hpa\":{\"behavior\":{},\"enabled\":true,\"maxReplicas\":10,\"metrics\":[],\"minReplicas\":1,\"targetCPUUtilizationPercentage\":50},\"image\":{\"pullPolicy\":\"IfNotPresent\",\"pullSecrets\":[],\"repository\":\"ghcr.io/janssenproject/jans/scim\",\"tag\":\"1.1.6_dev\"},\"lifecycle\":{},\"livenessProbe\":{\"httpGet\":{\"path\":\"/jans-scim/sys/health-check\",\"port\":8080},\"initialDelaySeconds\":30,\"periodSeconds\":30,\"timeoutSeconds\":5},\"pdb\":{\"enabled\":true,\"maxUnavailable\":\"90%\"},\"readinessProbe\":{\"httpGet\":{\"path\":\"/jans-scim/sys/health-check\",\"port\":8080},\"initialDelaySeconds\":25,\"periodSeconds\":25,\"timeoutSeconds\":5},\"replicas\":1,\"resources\":{\"limits\":{\"cpu\":\"1000m\",\"memory\":\"1200Mi\"},\"requests\":{\"cpu\":\"1000m\",\"memory\":\"1200Mi\"}},\"service\":{\"name\":\"http-scim\",\"port\":8080},\"topologySpreadConstraints\":{},\"usrEnvs\":{\"normal\":{},\"secret\":{}},\"volumeMounts\":[],\"volumes\":[]} System for Cross-domain Identity Management (SCIM) version 2.0 scim.additionalAnnotations object {} Additional annotations that will be added across the gateway in the format of scim.additionalLabels object {} Additional labels that will be added across the gateway in the format of scim.customScripts list [] Add custom scripts that have been mounted to run before the entrypoint. - /tmp/custom.sh - /tmp/custom2.sh scim.dnsConfig object {} Add custom dns config scim.dnsPolicy string \"\" Add custom dns policy scim.hpa object {\"behavior\":{},\"enabled\":true,\"maxReplicas\":10,\"metrics\":[],\"minReplicas\":1,\"targetCPUUtilizationPercentage\":50} Configure the HorizontalPodAutoscaler scim.hpa.behavior object {} Scaling Policies scim.hpa.metrics list [] metrics if targetCPUUtilizationPercentage is not set scim.image.pullPolicy string \"IfNotPresent\" Image pullPolicy to use for deploying. scim.image.pullSecrets list [] Image Pull Secrets scim.image.repository string \"ghcr.io/janssenproject/jans/scim\" Image to use for deploying. scim.image.tag string \"1.1.6_dev\" Image tag to use for deploying. scim.livenessProbe object {\"httpGet\":{\"path\":\"/jans-scim/sys/health-check\",\"port\":8080},\"initialDelaySeconds\":30,\"periodSeconds\":30,\"timeoutSeconds\":5} Configure the liveness healthcheck for SCIM if needed. scim.livenessProbe.httpGet.path string \"/jans-scim/sys/health-check\" http liveness probe endpoint scim.pdb object {\"enabled\":true,\"maxUnavailable\":\"90%\"} Configure the PodDisruptionBudget scim.readinessProbe object {\"httpGet\":{\"path\":\"/jans-scim/sys/health-check\",\"port\":8080},\"initialDelaySeconds\":25,\"periodSeconds\":25,\"timeoutSeconds\":5} Configure the readiness healthcheck for the SCIM if needed. scim.readinessProbe.httpGet.path string \"/jans-scim/sys/health-check\" http readiness probe endpoint scim.replicas int 1 Service replica number. scim.resources.limits.cpu string \"1000m\" CPU limit. scim.resources.limits.memory string \"1200Mi\" Memory limit. This value is used to calculate memory allocation for Java. Currently it only supports Mi . Please refrain from using other units. scim.resources.requests.cpu string \"1000m\" CPU request. scim.resources.requests.memory string \"1200Mi\" Memory request. scim.service.name string \"http-scim\" The name of the scim port within the scim service. Please keep it as default. scim.service.port int 8080 Port of the scim service. Please keep it as default. scim.topologySpreadConstraints object {} Configure the topology spread constraints. Notice this is a map NOT a list as in the upstream API https://kubernetes.io/docs/concepts/scheduling-eviction/topology-spread-constraints/ scim.usrEnvs object {\"normal\":{},\"secret\":{}} Add custom normal and secret envs to the service scim.usrEnvs.normal object {} Add custom normal envs to the service variable1: value1 scim.usrEnvs.secret object {} Add custom secret envs to the service variable1: value1 scim.volumeMounts list [] Configure any additional volumesMounts that need to be attached to the containers scim.volumes list [] Configure any additional volumes that need to be attached to the pod Autogenerated from chart metadata using helm-docs v1.13.1","title":"Values"},{"location":"supergluu/","tags":["Super Gluu","Introduction"],"text":"Super Gluu Documentation # Super Gluu is a free and secure two-factor authentication (2FA) mobile app. Super Gluu app can be used to achieve 2FA for web and mobile applications with Janssen Server , Gluu Flex , and Gluu Server working as authentication servers. Super Gluu documentation is organized into the following sections: User Guide Admin Guide Developer Guide Compatibility # Super Gluu is compatible with all versions of Gluu Flex. FIDO Security # During Super Gluu authentication, the Gluu Flex does more than look at the device ID to grant access. Super Gluu uses the Gluu Flex Server's FIDO U2F endpoints to enroll a public key. The private key is stored on the device. At authentication time, the Gluu Flex sends a challenge-response to the device to check for the corresponding private key. This adds an extra layer of security to Super Gluu push notification authentications. How to Use Super Gluu # Super Gluu is tightly bundled with Janssen. Follow the Flex installation guide to deploy Gluu Flex, then follow the Super Gluu admin guide to configure and begin using Super Gluu for strong authentication. Workflows # Super Gluu supports multiple workflows, including: A one-step, passwordless authentication, where the person scans a QR code with their Super Gluu app and the Gluu Flex looks up which person is associated with that device. A two-step authentication, where the person enters their username and then receives an out-of-band push notification to the mobile device to authorize access (a.k.a identifier first authentication). A two-step authentication, where the person enters their username and password and then receives an out-of-band push notification to the mobile device to authorize access. In all scenarios, users are prompted to scan a QR code on their first Super Gluu authentication to bind their device and account. In the second and third workflows listed above, users begin receiving push notifications for all authentications after the initial device registration process. Testing locally # Super Gluu security is based on SSL and therefore expects a public server with valid certificates. To test locally on a non-public server, follow these steps Download Super Gluu # Super Gluu is available for free on the iOS and Android app marketplaces! Download the Android app Download the iOS app Contributors # The next version of Super Gluu will support localization in many languages. We'd like to extend our sincere appreciation to the following people for helping translate Super Gluu content: Jose Gonzalez, Gluu Gasmyr Mougang, Gluu Yumi Sano, iBridge Andrea Patricelli, Tirasa Yuriy Zabrovarrnay, Gluu Aliaksander Sameseu, Gluu Andre Koot, Nixu Mohammad Abudayyeh, Gluu Ganesh Dutt Sharma, Gluu Mohib Zico, Gluu Mustafa Baser, Gluu","title":"Super Gluu Documentation"},{"location":"supergluu/#super-gluu-documentation","text":"Super Gluu is a free and secure two-factor authentication (2FA) mobile app. Super Gluu app can be used to achieve 2FA for web and mobile applications with Janssen Server , Gluu Flex , and Gluu Server working as authentication servers. Super Gluu documentation is organized into the following sections: User Guide Admin Guide Developer Guide","title":"Super Gluu Documentation"},{"location":"supergluu/#compatibility","text":"Super Gluu is compatible with all versions of Gluu Flex.","title":"Compatibility"},{"location":"supergluu/#fido-security","text":"During Super Gluu authentication, the Gluu Flex does more than look at the device ID to grant access. Super Gluu uses the Gluu Flex Server's FIDO U2F endpoints to enroll a public key. The private key is stored on the device. At authentication time, the Gluu Flex sends a challenge-response to the device to check for the corresponding private key. This adds an extra layer of security to Super Gluu push notification authentications.","title":"FIDO Security"},{"location":"supergluu/#how-to-use-super-gluu","text":"Super Gluu is tightly bundled with Janssen. Follow the Flex installation guide to deploy Gluu Flex, then follow the Super Gluu admin guide to configure and begin using Super Gluu for strong authentication.","title":"How to Use Super Gluu"},{"location":"supergluu/#workflows","text":"Super Gluu supports multiple workflows, including: A one-step, passwordless authentication, where the person scans a QR code with their Super Gluu app and the Gluu Flex looks up which person is associated with that device. A two-step authentication, where the person enters their username and then receives an out-of-band push notification to the mobile device to authorize access (a.k.a identifier first authentication). A two-step authentication, where the person enters their username and password and then receives an out-of-band push notification to the mobile device to authorize access. In all scenarios, users are prompted to scan a QR code on their first Super Gluu authentication to bind their device and account. In the second and third workflows listed above, users begin receiving push notifications for all authentications after the initial device registration process.","title":"Workflows"},{"location":"supergluu/#testing-locally","text":"Super Gluu security is based on SSL and therefore expects a public server with valid certificates. To test locally on a non-public server, follow these steps","title":"Testing locally"},{"location":"supergluu/#download-super-gluu","text":"Super Gluu is available for free on the iOS and Android app marketplaces! Download the Android app Download the iOS app","title":"Download Super Gluu"},{"location":"supergluu/#contributors","text":"The next version of Super Gluu will support localization in many languages. We'd like to extend our sincere appreciation to the following people for helping translate Super Gluu content: Jose Gonzalez, Gluu Gasmyr Mougang, Gluu Yumi Sano, iBridge Andrea Patricelli, Tirasa Yuriy Zabrovarrnay, Gluu Aliaksander Sameseu, Gluu Andre Koot, Nixu Mohammad Abudayyeh, Gluu Ganesh Dutt Sharma, Gluu Mohib Zico, Gluu Mustafa Baser, Gluu","title":"Contributors"},{"location":"supergluu/admin-guide/","tags":["Super Gluu","administration","configuration"],"text":"Super Gluu Administration Guide # Obtaining an SSA # In order to set up Super Gluu, the administrator must obtain a Software Statement Assertion from Agama Lab . Login with GitHub or email, then sign up for a SCAN subscription. The free tier will give you 500 credits, which can be used for 500 SuperGluu API calls (1 call = 1 credit). Then, go over to the SSA tab and create a new SSA with the supergluu software role and an expiry date of your choice. Your SSA will no longer be useable after that date. After creating the SSA, you can click on Details and view the base64 encoded string of characters that represent the SSA. You will need this string during setup. Configuration on Gluu Flex # Log into Flex UI Navigate to Admin > Scripts > super_gluu Use the following properties: AS_SSA : Your base64 encoded SSA string from Agama Lab AS_ENDPOINT : https://account.gluu.org The rest of the values can be left as provided Enable super_gluu script Navigate to FIDO and Enable SuperGluu At this point, the Super Gluu module on Gluu Flex is configured and ready. This means that, using OpenID Connect acr_values , applications can now request Super Gluu authentication for users. You can verify this by going to the super_gluu script properties and seeing that the AS_CLIENT_ID and AS_CLIENT_SECRET fields are now populated. Configuration on Gluu Server 4.x # To get started, log into the Gluu Server dashboard (a.k.a. oxTrust) and do the following: Navigate to Configuration > Manage Custom Scripts . In the Person Authentication tab find the super_gluu authentication module. Use the following properties: AS_SSA : Your base64 encoded SSA string from Agama Lab AS_ENDPOINT : https://account.gluu.org The rest of the values can be left as provided Scroll down and find the Enable check box. Enable the script by clicking the check box. Scroll to the bottom of the page and click Update . Now Super Gluu is an available authentication mechanism for your Gluu Server. This means that, using OpenID Connect acr_values , applications can now request Super Gluu authentication for users. You can verify this by going to the super_gluu script properties and seeing that the AS_CLIENT_ID and AS_CLIENT_SECRET fields are now populated. Migration from old setups # If you are using a setup from before SCAN was implemented, you will need to migrate to the latest super_gluu interception script. Obtain the latest super_gluu interception script for Gluu Server or Jans Open the script configuration using one of the methods mentioned above, and navigate to super_gluu Replace the contents of the script with the new one Disable the script, and click Update . This will update the properties of the script configuration. Populate the AS_SSA and AS_ENDPOINT fields as described above. Enable the script by clicking the Enable check box Scroll to the bottom of the page and click Update The latest version of Super Gluu is now enabled on your server. Note To make sure Super Gluu has been enabled successfully, you can check your Gluu Server's OpenID Connect configuration by navigating to the following URL: https:///.well-known/openid-configuration . Find acr_values_supported and you should see super_gluu . Test 2FA Authentication Flow # To test the Super Gluu configuration from end to end, an administrator can follow the steps below: Change the default authentication method to super_gluu using this guide Keep this browser window active so you can revert the authentication method to the default one. Prepare your mobile device by following Super Gluu mobile app user guide Perform tests using a test user","title":"Administration Guide"},{"location":"supergluu/admin-guide/#super-gluu-administration-guide","text":"","title":"Super Gluu Administration Guide"},{"location":"supergluu/admin-guide/#obtaining-an-ssa","text":"In order to set up Super Gluu, the administrator must obtain a Software Statement Assertion from Agama Lab . Login with GitHub or email, then sign up for a SCAN subscription. The free tier will give you 500 credits, which can be used for 500 SuperGluu API calls (1 call = 1 credit). Then, go over to the SSA tab and create a new SSA with the supergluu software role and an expiry date of your choice. Your SSA will no longer be useable after that date. After creating the SSA, you can click on Details and view the base64 encoded string of characters that represent the SSA. You will need this string during setup.","title":"Obtaining an SSA"},{"location":"supergluu/admin-guide/#configuration-on-gluu-flex","text":"Log into Flex UI Navigate to Admin > Scripts > super_gluu Use the following properties: AS_SSA : Your base64 encoded SSA string from Agama Lab AS_ENDPOINT : https://account.gluu.org The rest of the values can be left as provided Enable super_gluu script Navigate to FIDO and Enable SuperGluu At this point, the Super Gluu module on Gluu Flex is configured and ready. This means that, using OpenID Connect acr_values , applications can now request Super Gluu authentication for users. You can verify this by going to the super_gluu script properties and seeing that the AS_CLIENT_ID and AS_CLIENT_SECRET fields are now populated.","title":"Configuration on Gluu Flex"},{"location":"supergluu/admin-guide/#configuration-on-gluu-server-4x","text":"To get started, log into the Gluu Server dashboard (a.k.a. oxTrust) and do the following: Navigate to Configuration > Manage Custom Scripts . In the Person Authentication tab find the super_gluu authentication module. Use the following properties: AS_SSA : Your base64 encoded SSA string from Agama Lab AS_ENDPOINT : https://account.gluu.org The rest of the values can be left as provided Scroll down and find the Enable check box. Enable the script by clicking the check box. Scroll to the bottom of the page and click Update . Now Super Gluu is an available authentication mechanism for your Gluu Server. This means that, using OpenID Connect acr_values , applications can now request Super Gluu authentication for users. You can verify this by going to the super_gluu script properties and seeing that the AS_CLIENT_ID and AS_CLIENT_SECRET fields are now populated.","title":"Configuration on Gluu Server 4.x"},{"location":"supergluu/admin-guide/#migration-from-old-setups","text":"If you are using a setup from before SCAN was implemented, you will need to migrate to the latest super_gluu interception script. Obtain the latest super_gluu interception script for Gluu Server or Jans Open the script configuration using one of the methods mentioned above, and navigate to super_gluu Replace the contents of the script with the new one Disable the script, and click Update . This will update the properties of the script configuration. Populate the AS_SSA and AS_ENDPOINT fields as described above. Enable the script by clicking the Enable check box Scroll to the bottom of the page and click Update The latest version of Super Gluu is now enabled on your server. Note To make sure Super Gluu has been enabled successfully, you can check your Gluu Server's OpenID Connect configuration by navigating to the following URL: https:///.well-known/openid-configuration . Find acr_values_supported and you should see super_gluu .","title":"Migration from old setups"},{"location":"supergluu/admin-guide/#test-2fa-authentication-flow","text":"To test the Super Gluu configuration from end to end, an administrator can follow the steps below: Change the default authentication method to super_gluu using this guide Keep this browser window active so you can revert the authentication method to the default one. Prepare your mobile device by following Super Gluu mobile app user guide Perform tests using a test user","title":"Test 2FA Authentication Flow"},{"location":"supergluu/developer-guide/","tags":["Super Gluu","Developer"],"text":"Super Gluu Developer Guide # Super Gluu is a two-factor authentication mobile application for iOS and Android. Super Gluu can be used as a strong authentication mechanism to access resources that are protected by Gluu's free open source central authentication server, called the Gluu Server . The below documentation describes what is happening during user enrollment and authentication. QR Code # During enrollment and authentication, the app goes through a few steps: The user scans the QR code, which contains identification data in the following format: { \"app\" : \"https://example.gluu.org\", \"state\" : \"dek4nwk6-dk56-sr43-4frt-4jfi30fltimd\" \"issuer\" : \"https://example.gluu.org\" \"created\" : \"2016-06-12T12:00:01.874000\" } Data from the QR code is changed into Fido U2F metadata: String discoveryUrl = oxPush2Request.getIssuer(); discoveryUrl += \"/.well-known/fido-u2f-configuration\"; final String discoveryJson = CommunicationService.get(discoveryUrl, null); final U2fMetaData u2fMetaData = new Gson().fromJson(discoveryJson, U2fMetaData.class); This metadata is sent to the server: ``` final List keyHandles = dataStore.getKeyHandlesByIssuerAndAppId(oxPush2Request.getIssuer(), oxPush2Request.getApp()); final boolean isEnroll = (keyHandles.size() == 0) || StringUtils.equals(oxPush2Request.getMethod(), \"enroll\"); final String u2fEndpoint; if (isEnroll) u2fEndpoint = u2fMetaData.getRegistrationEndpoint();// if enroll then get registration endpoint } else { u2fEndpoint = u2fMetaData.getAuthenticationEndpoint();// if authentication then get corresponding endpoint } validChallengeJsonResponse = CommunicationService.get(u2fEndpoint, parameters); ``` When the result comes back, it decides whether to enroll a new device or authenticate an existing one: if (isEnroll) { tokenResponse = oxPush2RequestListener.onEnroll(challengeJson, oxPush2Request, isDeny); } else { tokenResponse = oxPush2RequestListener.onSign(challengeJson, u2fMetaData.getIssuer(), isDeny); } Enrollment Process # If you scan a QR code for the first time and your device's UDID isn't attached to your user ID, the app will enroll it. First, it needs to prepare the data properties, as follows: > String version = request.getString(JSON_PROPERTY_VERSION); > String appParam = request.getString(JSON_PROPERTY_APP_ID); > String challenge = request.getString(JSON_PROPERTY_SERVER_CHALLENGE); > String origin = oxPush2Request.getIssuer(); > > EnrollmentResponse enrollmentResponse = u2fKey.register(new EnrollmentRequest(version, appParam, challenge, oxPush2Request)); During registration, the app generates a unique keyHandle and keyPair (public/private keys) to sign all data and uses an ECC algorithm to encode the required data, as follows: > TokenEntry tokenEntry = new TokenEntry(keyPairGenerator.keyPairToJson(keyPair), enrollmentRequest.getApplication(), enrollmentRequest.getOxPush2Request().getIssuer()); > . > . > . > dataStore.storeTokenEntry(keyHandle, tokenEntry); > byte[] userPublicKey = keyPairGenerator.encodePublicKey(keyPair.getPublic()); > > byte[] applicationSha256 = DigestUtils.sha256(application); > byte[] challengeSha256 = DigestUtils.sha256(challenge); > byte[] signedData = rawMessageCodec.encodeRegistrationSignedBytes(applicationSha256, challengeSha256, keyHandle, userPublicKey); > byte[] signature = keyPairGenerator.sign(signedData, certificatePrivateKey); > return new EnrollmentResponse(userPublicKey, keyHandle, vendorCertificate, signature); Now, all the data is converted into one-byte array, then one additional parameter is added, determining if the request is approved or denied, as follows: > JSONObject clientData = new JSONObject(); > if (isDeny){ > clientData.put(JSON_PROPERTY_REQUEST_TYPE, REGISTER_CANCEL_TYPE);//Deny > } else { > clientData.put(JSON_PROPERTY_REQUEST_TYPE, REQUEST_TYPE_REGISTER);//Approve > } > clientData.put(JSON_PROPERTY_SERVER_CHALLENGE, challenge); > clientData.put(JSON_PROPERTY_SERVER_ORIGIN, origin); > > String clientDataString = clientData.toString(); > byte[] resp = rawMessageCodec.encodeRegisterResponse(enrollmentResponse); > > JSONObject response = new JSONObject(); > response.put(\"registrationData\", Utils.base64UrlEncode(resp)); > response.put(\"clientData\", Utils.base64UrlEncode(clientDataString.getBytes(Charset.forName(\"ASCII\")))); > response.put(\"deviceData\", Utils.base64UrlEncode(deviceDataString.getBytes(Charset.forName(\"ASCII\")))); > > TokenResponse tokenResponse = new TokenResponse(); > tokenResponse.setResponse(response.toString()); > tokenResponse.setChallenge(new String(challenge)); > tokenResponse.setKeyHandle(new String(enrollmentResponse.getKeyHandle())); > > return tokenResponse; For authentication, all information is associated with your device UDID and the app retrieves the data from the data store each time, as follows: > TokenEntry tokenEntry = dataStore.getTokenEntry(keyHandle); > String keyPairJson = tokenEntry.getKeyPair(); > keyPair = keyPairGenerator.keyPairFromJson(keyPairJson); > int counter = dataStore.incrementCounter(keyHandle); > byte userPresence = userPresenceVerifier.verifyUserPresence(); > byte[] applicationSha256 = DigestUtils.sha256(application); > byte[] challengeSha256 = DigestUtils.sha256(challenge); > byte[] signedData = rawMessageCodec.encodeAuthenticateSignedBytes(applicationSha256, userPresence, counter, challengeSha256); > return new AuthenticateResponse(userPresence, counter, signature); The onEnroll and onSign methods prepare the parameters and data before the call to the server. For more information about these two methods, see the Super Gluu Git repo. Now, the app makes one last call to the server: > final Map parameters = new HashMap(); > parameters.put(\"username\", oxPush2Request.getUserName()); > parameters.put(\"tokenResponse\", tokenResponse.getResponse()); > > final String resultJsonResponse = CommunicationService.post(u2fEndpoint, parameters); The string resultJsonResponse contains the JSON result. The app extracts some additional information from this result. Check enrollment or authentication success using the u2fOperationResult.getStatus() field, as follows: > LogInfo log = new LogInfo(); > log.setIssuer(oxPush2Request.getIssuer()); > log.setUserName(oxPush2Request.getUserName()); > log.setLocationIP(oxPush2Request.getLocationIP()); > log.setLocationAddress(oxPush2Request.getLocationCity()); > log.setCreatedDate(String.valueOf(System.currentTimeMillis()));//oxPush2Request.getCreated()); > log.setMethod(oxPush2Request.getMethod()); Testing locally # The following is a method for testing Super Gluu locally on a non-public server. This guide assumes a Gluu Server has been installed and is operational. Warning The following testing steps mimic a MITM attack, so needless to say, these instructions are for development purposes only! In the Gluu Server VM settings, change the network adapter connection type from NAT to Bridged; The Gluu Server and smartphone should be connected to WiFi on the same local network Log into the VM and run ifconfig in the terminal to get the IP address of the Gluu Server In oxTrust, enable the Super Gluu authentication script Update the host file on the machine where you are running the browser to log in. Example: 192.168.1.232 c67.example.info Run ipconfig / ifconfig on the machine where you are planning to run your DNS server. Configure any DNS server to allow resovle u144.example.info.=192.168.1.232 . For example you can use a lightweight WindowsDNS DNS proxy server Create a dns.config file in the folder with dedserver.jar. Example file content: u144.example.info.=192.168.1.232 Checkut and build https://github.com/JonahAragon/WindowsDNS Run the DNS server using a command like this: java -jar dedserver.jar Create a dns.config file in the folder with dedserver.jar . Example file content: u144.example.info.=192.168.1.232 Run the DNS server using a command like this: java -jar dedserver.jar On your mobile phone, open the WiFi connection details and specify the DNS server IP from Step 6 Now you can test Super Gluu After you finish testing, don't forget to change your WiFi connection type on the mobile phone back to use the automatic settings.","title":"Developer Guide"},{"location":"supergluu/developer-guide/#super-gluu-developer-guide","text":"Super Gluu is a two-factor authentication mobile application for iOS and Android. Super Gluu can be used as a strong authentication mechanism to access resources that are protected by Gluu's free open source central authentication server, called the Gluu Server . The below documentation describes what is happening during user enrollment and authentication.","title":"Super Gluu Developer Guide"},{"location":"supergluu/developer-guide/#qr-code","text":"During enrollment and authentication, the app goes through a few steps: The user scans the QR code, which contains identification data in the following format: { \"app\" : \"https://example.gluu.org\", \"state\" : \"dek4nwk6-dk56-sr43-4frt-4jfi30fltimd\" \"issuer\" : \"https://example.gluu.org\" \"created\" : \"2016-06-12T12:00:01.874000\" } Data from the QR code is changed into Fido U2F metadata: String discoveryUrl = oxPush2Request.getIssuer(); discoveryUrl += \"/.well-known/fido-u2f-configuration\"; final String discoveryJson = CommunicationService.get(discoveryUrl, null); final U2fMetaData u2fMetaData = new Gson().fromJson(discoveryJson, U2fMetaData.class); This metadata is sent to the server: ``` final List keyHandles = dataStore.getKeyHandlesByIssuerAndAppId(oxPush2Request.getIssuer(), oxPush2Request.getApp()); final boolean isEnroll = (keyHandles.size() == 0) || StringUtils.equals(oxPush2Request.getMethod(), \"enroll\"); final String u2fEndpoint; if (isEnroll) u2fEndpoint = u2fMetaData.getRegistrationEndpoint();// if enroll then get registration endpoint } else { u2fEndpoint = u2fMetaData.getAuthenticationEndpoint();// if authentication then get corresponding endpoint } validChallengeJsonResponse = CommunicationService.get(u2fEndpoint, parameters); ``` When the result comes back, it decides whether to enroll a new device or authenticate an existing one: if (isEnroll) { tokenResponse = oxPush2RequestListener.onEnroll(challengeJson, oxPush2Request, isDeny); } else { tokenResponse = oxPush2RequestListener.onSign(challengeJson, u2fMetaData.getIssuer(), isDeny); }","title":"QR Code"},{"location":"supergluu/developer-guide/#enrollment-process","text":"If you scan a QR code for the first time and your device's UDID isn't attached to your user ID, the app will enroll it. First, it needs to prepare the data properties, as follows: > String version = request.getString(JSON_PROPERTY_VERSION); > String appParam = request.getString(JSON_PROPERTY_APP_ID); > String challenge = request.getString(JSON_PROPERTY_SERVER_CHALLENGE); > String origin = oxPush2Request.getIssuer(); > > EnrollmentResponse enrollmentResponse = u2fKey.register(new EnrollmentRequest(version, appParam, challenge, oxPush2Request)); During registration, the app generates a unique keyHandle and keyPair (public/private keys) to sign all data and uses an ECC algorithm to encode the required data, as follows: > TokenEntry tokenEntry = new TokenEntry(keyPairGenerator.keyPairToJson(keyPair), enrollmentRequest.getApplication(), enrollmentRequest.getOxPush2Request().getIssuer()); > . > . > . > dataStore.storeTokenEntry(keyHandle, tokenEntry); > byte[] userPublicKey = keyPairGenerator.encodePublicKey(keyPair.getPublic()); > > byte[] applicationSha256 = DigestUtils.sha256(application); > byte[] challengeSha256 = DigestUtils.sha256(challenge); > byte[] signedData = rawMessageCodec.encodeRegistrationSignedBytes(applicationSha256, challengeSha256, keyHandle, userPublicKey); > byte[] signature = keyPairGenerator.sign(signedData, certificatePrivateKey); > return new EnrollmentResponse(userPublicKey, keyHandle, vendorCertificate, signature); Now, all the data is converted into one-byte array, then one additional parameter is added, determining if the request is approved or denied, as follows: > JSONObject clientData = new JSONObject(); > if (isDeny){ > clientData.put(JSON_PROPERTY_REQUEST_TYPE, REGISTER_CANCEL_TYPE);//Deny > } else { > clientData.put(JSON_PROPERTY_REQUEST_TYPE, REQUEST_TYPE_REGISTER);//Approve > } > clientData.put(JSON_PROPERTY_SERVER_CHALLENGE, challenge); > clientData.put(JSON_PROPERTY_SERVER_ORIGIN, origin); > > String clientDataString = clientData.toString(); > byte[] resp = rawMessageCodec.encodeRegisterResponse(enrollmentResponse); > > JSONObject response = new JSONObject(); > response.put(\"registrationData\", Utils.base64UrlEncode(resp)); > response.put(\"clientData\", Utils.base64UrlEncode(clientDataString.getBytes(Charset.forName(\"ASCII\")))); > response.put(\"deviceData\", Utils.base64UrlEncode(deviceDataString.getBytes(Charset.forName(\"ASCII\")))); > > TokenResponse tokenResponse = new TokenResponse(); > tokenResponse.setResponse(response.toString()); > tokenResponse.setChallenge(new String(challenge)); > tokenResponse.setKeyHandle(new String(enrollmentResponse.getKeyHandle())); > > return tokenResponse; For authentication, all information is associated with your device UDID and the app retrieves the data from the data store each time, as follows: > TokenEntry tokenEntry = dataStore.getTokenEntry(keyHandle); > String keyPairJson = tokenEntry.getKeyPair(); > keyPair = keyPairGenerator.keyPairFromJson(keyPairJson); > int counter = dataStore.incrementCounter(keyHandle); > byte userPresence = userPresenceVerifier.verifyUserPresence(); > byte[] applicationSha256 = DigestUtils.sha256(application); > byte[] challengeSha256 = DigestUtils.sha256(challenge); > byte[] signedData = rawMessageCodec.encodeAuthenticateSignedBytes(applicationSha256, userPresence, counter, challengeSha256); > return new AuthenticateResponse(userPresence, counter, signature); The onEnroll and onSign methods prepare the parameters and data before the call to the server. For more information about these two methods, see the Super Gluu Git repo. Now, the app makes one last call to the server: > final Map parameters = new HashMap(); > parameters.put(\"username\", oxPush2Request.getUserName()); > parameters.put(\"tokenResponse\", tokenResponse.getResponse()); > > final String resultJsonResponse = CommunicationService.post(u2fEndpoint, parameters); The string resultJsonResponse contains the JSON result. The app extracts some additional information from this result. Check enrollment or authentication success using the u2fOperationResult.getStatus() field, as follows: > LogInfo log = new LogInfo(); > log.setIssuer(oxPush2Request.getIssuer()); > log.setUserName(oxPush2Request.getUserName()); > log.setLocationIP(oxPush2Request.getLocationIP()); > log.setLocationAddress(oxPush2Request.getLocationCity()); > log.setCreatedDate(String.valueOf(System.currentTimeMillis()));//oxPush2Request.getCreated()); > log.setMethod(oxPush2Request.getMethod());","title":"Enrollment Process"},{"location":"supergluu/developer-guide/#testing-locally","text":"The following is a method for testing Super Gluu locally on a non-public server. This guide assumes a Gluu Server has been installed and is operational. Warning The following testing steps mimic a MITM attack, so needless to say, these instructions are for development purposes only! In the Gluu Server VM settings, change the network adapter connection type from NAT to Bridged; The Gluu Server and smartphone should be connected to WiFi on the same local network Log into the VM and run ifconfig in the terminal to get the IP address of the Gluu Server In oxTrust, enable the Super Gluu authentication script Update the host file on the machine where you are running the browser to log in. Example: 192.168.1.232 c67.example.info Run ipconfig / ifconfig on the machine where you are planning to run your DNS server. Configure any DNS server to allow resovle u144.example.info.=192.168.1.232 . For example you can use a lightweight WindowsDNS DNS proxy server Create a dns.config file in the folder with dedserver.jar. Example file content: u144.example.info.=192.168.1.232 Checkut and build https://github.com/JonahAragon/WindowsDNS Run the DNS server using a command like this: java -jar dedserver.jar Create a dns.config file in the folder with dedserver.jar . Example file content: u144.example.info.=192.168.1.232 Run the DNS server using a command like this: java -jar dedserver.jar On your mobile phone, open the WiFi connection details and specify the DNS server IP from Step 6 Now you can test Super Gluu After you finish testing, don't forget to change your WiFi connection type on the mobile phone back to use the automatic settings.","title":"Testing locally"},{"location":"supergluu/user-guide/","tags":["Super Gluu","User Guide"],"text":"Super Gluu User Guide # This guide will show how to use the Super Gluu two-factor authentication mobile application. It covers the initial setup, managing keys and logs, and general settings. Note The screenshots below are shown in iOS. Android is roughly the same. Initial Setup # Camera Access Prompt # After installation, Super Gluu will request access to use your camera, which is used to scan a QR code to set up your two-factor authentication. Choose Login Method # For additional security, Super Gluu gives you the option to configure either a passcode or TouchID to access Super Gluu. This choice can be changed in the application settings later. Note After 5 unsuccessful attempts to enter the passcode, the app is locked for 10 minutes. Screen for the passcode and TouchID selection Screen for enabling passcode Screen for enabling TouchID Confirm Push Notification # Next, it will ask for permission to send push notifications from the Flex. This choice can be changed later in the device settings. More information about the push notification will be covered later in the document. Main Screen # After configuration, the main screen is displayed. It features the main enrollment button in the center and the menu button in the top right. QR Code Enrollment # To enroll a device, enter the credentials in your Flex web app to generate a QR code, then click the Scan QR Code button on the Super Gluu app's Home screen: After it scans the code and the server returns the request correctly, it will prompt to Approve or Deny . To continue the enrollment/authentication process, click Approve : The timer on the top right of the screen shows the time limit to choose to Approve or Deny . As time runs out, the number's color will change: yellow if it's under 20 seconds, red if it's under 10. Next, it will redirect to the main page and display a success message. Menu # After pressing the menu button, you'll get the option to view logs, keys, settings, and help files. You can also check the current app version in the bottom right corner. Tapping it for several seconds will show the details of the latest commit. Logs # Each time it enrolls or authenticates a device, the app will save corresponding logs in the Logs tab. The log details whether authentication was successful, with more details available if the log is tapped on. Clear these logs if desired by swiping left on the log, then tapping the red button. The Log tab will report the enrollment and authentication process and display who logged in, when, and from where. Just tap on the log to get to the information screen. The information screen contains data about: Flex name & server URL Username IP address & location Time & date Keys # This tab contains all available keys for each Flex. A key is a unique file that is generated during enrollment and is used to authenticate the device on the server. If a key for a server is deleted, enroll again with a new key. Note If you delete a key from your app but wish to re-enroll the same device against the same server, the corresponding entry for that device also needs to be removed from the user record in the Flex. To change a key's name, swipe left on it and tap the green button. To delete a key, swipe left on the key, then tap the red button. Settings # In the Settings tab, there are options to configure the passcode or TouchID. Push Notifications # Super Gluu can receive push notifications from Flex. The server can send an enrollment or authentication request to the application, as if it scanned the QR code directly. After choosing to receive push notifications either during initial setup or through the Settings tab later, enroll through the server. Super Gluu will send a token to the server, which will be used to send push notifications to the device. After receiving the notification, tap Approve or Deny directly from the push menu. Super Gluu can receive a notification when the application is running in the foreground. It will look just like the original authentication screen. Device Settings, iPad Support # There are a few options for Super Gluu in the device settings - push notifications, location, access to the camera, and passcode protection. Any change made in the device settings will take effect in the application. Super Gluu can run on iPads, and the layout is the same for all IOS devices. For more information, please see the Gluu Website","title":"User Guide"},{"location":"supergluu/user-guide/#super-gluu-user-guide","text":"This guide will show how to use the Super Gluu two-factor authentication mobile application. It covers the initial setup, managing keys and logs, and general settings. Note The screenshots below are shown in iOS. Android is roughly the same.","title":"Super Gluu User Guide"},{"location":"supergluu/user-guide/#initial-setup","text":"","title":"Initial Setup"},{"location":"supergluu/user-guide/#camera-access-prompt","text":"After installation, Super Gluu will request access to use your camera, which is used to scan a QR code to set up your two-factor authentication.","title":"Camera Access Prompt"},{"location":"supergluu/user-guide/#choose-login-method","text":"For additional security, Super Gluu gives you the option to configure either a passcode or TouchID to access Super Gluu. This choice can be changed in the application settings later. Note After 5 unsuccessful attempts to enter the passcode, the app is locked for 10 minutes. Screen for the passcode and TouchID selection Screen for enabling passcode Screen for enabling TouchID","title":"Choose Login Method"},{"location":"supergluu/user-guide/#confirm-push-notification","text":"Next, it will ask for permission to send push notifications from the Flex. This choice can be changed later in the device settings. More information about the push notification will be covered later in the document.","title":"Confirm Push Notification"},{"location":"supergluu/user-guide/#main-screen","text":"After configuration, the main screen is displayed. It features the main enrollment button in the center and the menu button in the top right.","title":"Main Screen"},{"location":"supergluu/user-guide/#qr-code-enrollment","text":"To enroll a device, enter the credentials in your Flex web app to generate a QR code, then click the Scan QR Code button on the Super Gluu app's Home screen: After it scans the code and the server returns the request correctly, it will prompt to Approve or Deny . To continue the enrollment/authentication process, click Approve : The timer on the top right of the screen shows the time limit to choose to Approve or Deny . As time runs out, the number's color will change: yellow if it's under 20 seconds, red if it's under 10. Next, it will redirect to the main page and display a success message.","title":"QR Code Enrollment"},{"location":"supergluu/user-guide/#menu","text":"After pressing the menu button, you'll get the option to view logs, keys, settings, and help files. You can also check the current app version in the bottom right corner. Tapping it for several seconds will show the details of the latest commit.","title":"Menu"},{"location":"supergluu/user-guide/#logs","text":"Each time it enrolls or authenticates a device, the app will save corresponding logs in the Logs tab. The log details whether authentication was successful, with more details available if the log is tapped on. Clear these logs if desired by swiping left on the log, then tapping the red button. The Log tab will report the enrollment and authentication process and display who logged in, when, and from where. Just tap on the log to get to the information screen. The information screen contains data about: Flex name & server URL Username IP address & location Time & date","title":"Logs"},{"location":"supergluu/user-guide/#keys","text":"This tab contains all available keys for each Flex. A key is a unique file that is generated during enrollment and is used to authenticate the device on the server. If a key for a server is deleted, enroll again with a new key. Note If you delete a key from your app but wish to re-enroll the same device against the same server, the corresponding entry for that device also needs to be removed from the user record in the Flex. To change a key's name, swipe left on it and tap the green button. To delete a key, swipe left on the key, then tap the red button.","title":"Keys"},{"location":"supergluu/user-guide/#settings","text":"In the Settings tab, there are options to configure the passcode or TouchID.","title":"Settings"},{"location":"supergluu/user-guide/#push-notifications","text":"Super Gluu can receive push notifications from Flex. The server can send an enrollment or authentication request to the application, as if it scanned the QR code directly. After choosing to receive push notifications either during initial setup or through the Settings tab later, enroll through the server. Super Gluu will send a token to the server, which will be used to send push notifications to the device. After receiving the notification, tap Approve or Deny directly from the push menu. Super Gluu can receive a notification when the application is running in the foreground. It will look just like the original authentication screen.","title":"Push Notifications"},{"location":"supergluu/user-guide/#device-settings-ipad-support","text":"There are a few options for Super Gluu in the device settings - push notifications, location, access to the camera, and passcode protection. Any change made in the device settings will take effect in the application. Super Gluu can run on iPads, and the layout is the same for all IOS devices. For more information, please see the Gluu Website","title":"Device Settings, iPad Support"}]} \ No newline at end of file +{"config":{"indexing":"full","lang":["en"],"min_search_length":3,"prebuild_index":false,"separator":"[\\s\\-]+"},"docs":[{"location":"","text":"Gluu Flex Documentation # Introduction # Designed from the ground up to support cloud-native deployments, Gluu Flex is a self-hosted software stack to enable your organization to build a world-class digital identity platform to authenticate both people and software. With Helm charts available out of the box, Gluu Flex can handle the most demanding requirements for concurrency. Thanks to cloud-native auto-scaling and zero downtime updates, you can build a robust, multi-datacenter topology. You can take advantage of new cloud databases like Amazon Aurora and Google Spanner. Common use cases include: Single sign-on (SSO) Mobile authentication API access management Two-factor authentication (2FA) Customer identity and access management (CIAM) Identity federation Built on Janssen # Gluu Flex is a downstream product of the Linux Foundation Janssen Project . It was created for enterprise customers who want a commercially supported distribution, plus some additional tools to ease administration. Harness Low Code Authentication Flows with Agama # Gluu Flex uses Agama to offer an alternative way to build web-based authentication flows. Traditionally, person authentication flows are defined in the server with jython scripts that adhere to a predefined API. With Agama, flows are coded using a DSL (domain specific language) designed for the sole purpose of writing web flows. Agama flows are simpler, more intuitive, and quicker to build. Support # The Gluu Flex contract includes guaranteed response times and consultative support via our support portal . Looking for older documentation versions? # The Janssen Project posts the last five versions of the documentation. If you are looking for older versions, you can find them unprocessed in the docs folder. Select the version of choice from the tag dropdown in GitHub. If you want to process them you may do so by following the steps below : Testing Documentation Changes Locally # While contributing documentation to official Gluu documentation it is important to make sure that documents meet style guidelines and have been proofread to remove any typographical or grammatical errors. Gluu uses Material for MkDocs to create the documentation site. Before new content is pushed to the repository on GitHub, it should be tested locally by the author. Author can do this by deploying Material for MkDocs locally. High-level steps involve: Install Material for MkDocs Install required plugins Preview as you write","title":"Overview"},{"location":"#gluu-flex-documentation","text":"","title":"Gluu Flex Documentation"},{"location":"#introduction","text":"Designed from the ground up to support cloud-native deployments, Gluu Flex is a self-hosted software stack to enable your organization to build a world-class digital identity platform to authenticate both people and software. With Helm charts available out of the box, Gluu Flex can handle the most demanding requirements for concurrency. Thanks to cloud-native auto-scaling and zero downtime updates, you can build a robust, multi-datacenter topology. You can take advantage of new cloud databases like Amazon Aurora and Google Spanner. Common use cases include: Single sign-on (SSO) Mobile authentication API access management Two-factor authentication (2FA) Customer identity and access management (CIAM) Identity federation","title":"Introduction"},{"location":"#built-on-janssen","text":"Gluu Flex is a downstream product of the Linux Foundation Janssen Project . It was created for enterprise customers who want a commercially supported distribution, plus some additional tools to ease administration.","title":"Built on Janssen"},{"location":"#harness-low-code-authentication-flows-with-agama","text":"Gluu Flex uses Agama to offer an alternative way to build web-based authentication flows. Traditionally, person authentication flows are defined in the server with jython scripts that adhere to a predefined API. With Agama, flows are coded using a DSL (domain specific language) designed for the sole purpose of writing web flows. Agama flows are simpler, more intuitive, and quicker to build.","title":"Harness Low Code Authentication Flows with Agama"},{"location":"#support","text":"The Gluu Flex contract includes guaranteed response times and consultative support via our support portal .","title":"Support"},{"location":"#looking-for-older-documentation-versions","text":"The Janssen Project posts the last five versions of the documentation. If you are looking for older versions, you can find them unprocessed in the docs folder. Select the version of choice from the tag dropdown in GitHub. If you want to process them you may do so by following the steps below :","title":"Looking for older documentation versions?"},{"location":"#testing-documentation-changes-locally","text":"While contributing documentation to official Gluu documentation it is important to make sure that documents meet style guidelines and have been proofread to remove any typographical or grammatical errors. Gluu uses Material for MkDocs to create the documentation site. Before new content is pushed to the repository on GitHub, it should be tested locally by the author. Author can do this by deploying Material for MkDocs locally. High-level steps involve: Install Material for MkDocs Install required plugins Preview as you write","title":"Testing Documentation Changes Locally"},{"location":"CHANGELOG/","text":"Changelog # 5.0.0-21 (2023-12-18) # Bug Fixes # prepare for 5.0.0-21 release ( cee44ca ) 5.0.0-20 (2023-11-16) # Features # aio chart ( #1436 ) ( a20a695 ) Bug Fixes # docs: update casa base URI ( #1440 ) ( 495536c ) prepare for 5.0.0-20 release ( f74643c ) 5.0.0-19 (2023-10-12) # Features # docs: remove Casa files from Flex ( a5b7fcd ) Bug Fixes # docs: remove Casa image assets ( 0b9f0b4 ) docs: update docs w.r.t casa move to Jans ( 5b7d3fd ) docs: update docs w.r.t casa move to Jans ( 16f647c ) prepare for 5.0.0-19 release ( 2d8e13d ) 5.0.0-18 (2023-09-23) # Features # adding configuration and logs details ( d136f3d ) updating configuration docs ( a1933e3 ) Bug Fixes # prepare for 5.0.0-18 release ( 29f822f ) prepare for 5.0.0-18 release ( 4af69cb ) versioning ( 1abf437 ) 5.0.0-16 (2023-08-14) # Bug Fixes # prepare for 5.0.0-16 release ( 699d534 ) 5.0.0-15 (2023-07-14) # Features # adding tags ( 7841e03 ) documentation of admin-ui #1063 ( 3cf1e7b ) documentation of admin-ui #1063 ( 48233d3 ) edit flex license contents ( 8d7f749 ) making changes as per review comments ( 1bcd39b ) making changes as per review comments ( 5c636fb ) Bug Fixes # doc: added How to configure SuperGluu in Flex ( 6b7beef ) doc: adding SG screenshot - 2 ( e06bd79 ) doc: adding SG screenshot-1 ( b581a03 ) doc: enable SG - 2 ( d86ec85 ) doc: Flex SG doc review - How to Use SuperGluu ( f564dd1 ) doc: hiding ad removal related doc ( 5354e84 ) doc: how to enable SG in Flex-UI ( 4851205 ) doc: index page flex ( 7d48422 ) doc: removing key list from user record info ( 01b671a ) docs: flex-ui SG -- Compatability ( f78c46a ) doc: SG flex - How to use Super Gluu-1 ( e07641c ) doc: sg flex - how to use Super Gluu-screenshot location ( 7798023 ) doc: sg workflows ( 601b237 ) docs: test SG authentication ( 32f6b24 ) doc: test authentication SG ( 6d0f550 ) doc: Test authentication user guide ( a554646 ) doc: uploading modified screenshot ( 0e9e0cf ) prepare for 5.0.0-15 release ( 664553a ) 5.0.0-14 (2023-06-12) # Bug Fixes # prepare for 5.0.0-14 release ( 9481f55 ) 5.0.0-13 (2023-05-12) # Bug Fixes # admin-ui: add apply button ( d334103 ) blockUI converted to functional component ( 4b8e7bd ) email_2fa_core/install.bat has been removed; ( f27e461 ) prepare for 5.0.13 release ( 8578827 ) profile details is distorted when multiple roles assigned to the user ( e4603d8 ) revert prod webpack config of static & fonts files ( 96fa135 ) 5.0.0-12 (2023-04-18) # Bug Fixes # prepare for 5.0.12 release ( 994c985 ) 5.0.0-11 (2023-04-06) # Bug Fixes # prepare for 5.0.11 release ( d3cc35a ) 5.0.0-10 (2023-03-16) # Bug Fixes # add cn license enforcment to chart ( 55fb0c9 ) prepare for 5.0.10 release ( 1ffcbc7 ) 5.0.0-9 (2023-03-09) # Bug Fixes # docs: ubuntu install download location ( bb3a5cd ) prepare for 5.0.0-9 release ( 716d309 ) 5.0.0-8 (2023-03-02) # Bug Fixes # prepare for 5.0.0-8 release ( 29e0cbb ) 5.0.0-7 (2023-02-22) # Bug Fixes # prepare for 5.0.0-7 release ( 7f96937 ) 5.0.0-4 (2022-12-08) # Bug Fixes # getting ready for a release ( a0de091 ) 5.0.0-3 (2022-11-08) # Features # admin-ui: reviewed previously updated dependencies #416 ( ab81760 ) Bug Fixes # getting ready to release 5.0.0-3 ( e8f3ecc ) Miscellaneous Chores # release 5.0.0-2 ( 06c6e64 )","title":"Changelog"},{"location":"CHANGELOG/#changelog","text":"","title":"Changelog"},{"location":"CHANGELOG/#500-21-2023-12-18","text":"","title":"5.0.0-21 (2023-12-18)"},{"location":"CHANGELOG/#bug-fixes","text":"prepare for 5.0.0-21 release ( cee44ca )","title":"Bug Fixes"},{"location":"CHANGELOG/#500-20-2023-11-16","text":"","title":"5.0.0-20 (2023-11-16)"},{"location":"CHANGELOG/#features","text":"aio chart ( #1436 ) ( a20a695 )","title":"Features"},{"location":"CHANGELOG/#bug-fixes_1","text":"docs: update casa base URI ( #1440 ) ( 495536c ) prepare for 5.0.0-20 release ( f74643c )","title":"Bug Fixes"},{"location":"CHANGELOG/#500-19-2023-10-12","text":"","title":"5.0.0-19 (2023-10-12)"},{"location":"CHANGELOG/#features_1","text":"docs: remove Casa files from Flex ( a5b7fcd )","title":"Features"},{"location":"CHANGELOG/#bug-fixes_2","text":"docs: remove Casa image assets ( 0b9f0b4 ) docs: update docs w.r.t casa move to Jans ( 5b7d3fd ) docs: update docs w.r.t casa move to Jans ( 16f647c ) prepare for 5.0.0-19 release ( 2d8e13d )","title":"Bug Fixes"},{"location":"CHANGELOG/#500-182023-09-23","text":"","title":"5.0.0-18(2023-09-23)"},{"location":"CHANGELOG/#features_2","text":"adding configuration and logs details ( d136f3d ) updating configuration docs ( a1933e3 )","title":"Features"},{"location":"CHANGELOG/#bug-fixes_3","text":"prepare for 5.0.0-18 release ( 29f822f ) prepare for 5.0.0-18 release ( 4af69cb ) versioning ( 1abf437 )","title":"Bug Fixes"},{"location":"CHANGELOG/#500-16-2023-08-14","text":"","title":"5.0.0-16 (2023-08-14)"},{"location":"CHANGELOG/#bug-fixes_4","text":"prepare for 5.0.0-16 release ( 699d534 )","title":"Bug Fixes"},{"location":"CHANGELOG/#500-15-2023-07-14","text":"","title":"5.0.0-15 (2023-07-14)"},{"location":"CHANGELOG/#features_3","text":"adding tags ( 7841e03 ) documentation of admin-ui #1063 ( 3cf1e7b ) documentation of admin-ui #1063 ( 48233d3 ) edit flex license contents ( 8d7f749 ) making changes as per review comments ( 1bcd39b ) making changes as per review comments ( 5c636fb )","title":"Features"},{"location":"CHANGELOG/#bug-fixes_5","text":"doc: added How to configure SuperGluu in Flex ( 6b7beef ) doc: adding SG screenshot - 2 ( e06bd79 ) doc: adding SG screenshot-1 ( b581a03 ) doc: enable SG - 2 ( d86ec85 ) doc: Flex SG doc review - How to Use SuperGluu ( f564dd1 ) doc: hiding ad removal related doc ( 5354e84 ) doc: how to enable SG in Flex-UI ( 4851205 ) doc: index page flex ( 7d48422 ) doc: removing key list from user record info ( 01b671a ) docs: flex-ui SG -- Compatability ( f78c46a ) doc: SG flex - How to use Super Gluu-1 ( e07641c ) doc: sg flex - how to use Super Gluu-screenshot location ( 7798023 ) doc: sg workflows ( 601b237 ) docs: test SG authentication ( 32f6b24 ) doc: test authentication SG ( 6d0f550 ) doc: Test authentication user guide ( a554646 ) doc: uploading modified screenshot ( 0e9e0cf ) prepare for 5.0.0-15 release ( 664553a )","title":"Bug Fixes"},{"location":"CHANGELOG/#500-14-2023-06-12","text":"","title":"5.0.0-14 (2023-06-12)"},{"location":"CHANGELOG/#bug-fixes_6","text":"prepare for 5.0.0-14 release ( 9481f55 )","title":"Bug Fixes"},{"location":"CHANGELOG/#500-13-2023-05-12","text":"","title":"5.0.0-13 (2023-05-12)"},{"location":"CHANGELOG/#bug-fixes_7","text":"admin-ui: add apply button ( d334103 ) blockUI converted to functional component ( 4b8e7bd ) email_2fa_core/install.bat has been removed; ( f27e461 ) prepare for 5.0.13 release ( 8578827 ) profile details is distorted when multiple roles assigned to the user ( e4603d8 ) revert prod webpack config of static & fonts files ( 96fa135 )","title":"Bug Fixes"},{"location":"CHANGELOG/#500-12-2023-04-18","text":"","title":"5.0.0-12 (2023-04-18)"},{"location":"CHANGELOG/#bug-fixes_8","text":"prepare for 5.0.12 release ( 994c985 )","title":"Bug Fixes"},{"location":"CHANGELOG/#500-11-2023-04-06","text":"","title":"5.0.0-11 (2023-04-06)"},{"location":"CHANGELOG/#bug-fixes_9","text":"prepare for 5.0.11 release ( d3cc35a )","title":"Bug Fixes"},{"location":"CHANGELOG/#500-10-2023-03-16","text":"","title":"5.0.0-10 (2023-03-16)"},{"location":"CHANGELOG/#bug-fixes_10","text":"add cn license enforcment to chart ( 55fb0c9 ) prepare for 5.0.10 release ( 1ffcbc7 )","title":"Bug Fixes"},{"location":"CHANGELOG/#500-9-2023-03-09","text":"","title":"5.0.0-9 (2023-03-09)"},{"location":"CHANGELOG/#bug-fixes_11","text":"docs: ubuntu install download location ( bb3a5cd ) prepare for 5.0.0-9 release ( 716d309 )","title":"Bug Fixes"},{"location":"CHANGELOG/#500-8-2023-03-02","text":"","title":"5.0.0-8 (2023-03-02)"},{"location":"CHANGELOG/#bug-fixes_12","text":"prepare for 5.0.0-8 release ( 29e0cbb )","title":"Bug Fixes"},{"location":"CHANGELOG/#500-7-2023-02-22","text":"","title":"5.0.0-7 (2023-02-22)"},{"location":"CHANGELOG/#bug-fixes_13","text":"prepare for 5.0.0-7 release ( 7f96937 )","title":"Bug Fixes"},{"location":"CHANGELOG/#500-4-2022-12-08","text":"","title":"5.0.0-4 (2022-12-08)"},{"location":"CHANGELOG/#bug-fixes_14","text":"getting ready for a release ( a0de091 )","title":"Bug Fixes"},{"location":"CHANGELOG/#500-3-2022-11-08","text":"","title":"5.0.0-3 (2022-11-08)"},{"location":"CHANGELOG/#features_4","text":"admin-ui: reviewed previously updated dependencies #416 ( ab81760 )","title":"Features"},{"location":"CHANGELOG/#bug-fixes_15","text":"getting ready to release 5.0.0-3 ( e8f3ecc )","title":"Bug Fixes"},{"location":"CHANGELOG/#miscellaneous-chores","text":"release 5.0.0-2 ( 06c6e64 )","title":"Miscellaneous Chores"},{"location":"admin/","text":"Gluu Flex Admin Guide # Overview # Gluu Flex is a commercially supported distribution of the Janssen Project , including the OpenID, OAuth, Config, FIDO, Casa, and SCIM Server components. Additionally, Flex includes the commercially licensed Flex Admin UI. Janssen Documentation # Central to Gluu Flex is the Janssen Project . Janssen enables organizations to build a scalable centralized authentication and authorization service using free open source software. Admin UI # The Gluu Flex Admin UI is a reactive web interface to simplify the management and configuration of your Auth Server. The Admin UI enables you to easily view and edit configuration properties, interception scripts, clients, and metrics in one place.","title":"Gluu Flex Admin Guide"},{"location":"admin/#gluu-flex-admin-guide","text":"","title":"Gluu Flex Admin Guide"},{"location":"admin/#overview","text":"Gluu Flex is a commercially supported distribution of the Janssen Project , including the OpenID, OAuth, Config, FIDO, Casa, and SCIM Server components. Additionally, Flex includes the commercially licensed Flex Admin UI.","title":"Overview"},{"location":"admin/#janssen-documentation","text":"Central to Gluu Flex is the Janssen Project . Janssen enables organizations to build a scalable centralized authentication and authorization service using free open source software.","title":"Janssen Documentation"},{"location":"admin/#admin-ui","text":"The Gluu Flex Admin UI is a reactive web interface to simplify the management and configuration of your Auth Server. The Admin UI enables you to easily view and edit configuration properties, interception scripts, clients, and metrics in one place.","title":"Admin UI"},{"location":"admin/config/","text":"Configuring Gluu Flex # Overview # After installing, there are four primary strategies to configure Gluu Flex. Text-based User Interface (TUI) # The current recommendation is to use the Janssen TUI to configure Flex components. The TUI calls the Config API to perform ad hoc configuration, and instructions can be found in the Janssen documentation here. CURL Commands # As an alternative, the Config API can be called directly using CURL commands. Command Line Interface (CLI) # If needed, a command-line alternative to the TUI is available. Instructions can be found in the Janssen documentation here. Admin UI # The Gluu Flex Admin UI is a reactive web interface to simplify the management and configuration of your Auth Server. The Admin UI enables you to easily view and edit configuration properties, interception scripts, clients, and metrics in one place. The Admin UI can be accessed by accessing the hostname set during installation in the browser.","title":"Configuration"},{"location":"admin/config/#configuring-gluu-flex","text":"","title":"Configuring Gluu Flex"},{"location":"admin/config/#overview","text":"After installing, there are four primary strategies to configure Gluu Flex.","title":"Overview"},{"location":"admin/config/#text-based-user-interface-tui","text":"The current recommendation is to use the Janssen TUI to configure Flex components. The TUI calls the Config API to perform ad hoc configuration, and instructions can be found in the Janssen documentation here.","title":"Text-based User Interface (TUI)"},{"location":"admin/config/#curl-commands","text":"As an alternative, the Config API can be called directly using CURL commands.","title":"CURL Commands"},{"location":"admin/config/#command-line-interface-cli","text":"If needed, a command-line alternative to the TUI is available. Instructions can be found in the Janssen documentation here.","title":"Command Line Interface (CLI)"},{"location":"admin/config/#admin-ui","text":"The Gluu Flex Admin UI is a reactive web interface to simplify the management and configuration of your Auth Server. The Admin UI enables you to easily view and edit configuration properties, interception scripts, clients, and metrics in one place. The Admin UI can be accessed by accessing the hostname set during installation in the browser.","title":"Admin UI"},{"location":"admin/admin-ui/","text":"Where is this content? # The Gluu Flex documentation is a work in progress, and this document is currently a draft. Keep an eye on this page for updates.","title":"Index"},{"location":"admin/admin-ui/#where-is-this-content","text":"The Gluu Flex documentation is a work in progress, and this document is currently a draft. Keep an eye on this page for updates.","title":"Where is this content?"},{"location":"admin/admin-ui/admin-menu/","tags":["administration","admin-ui","admin","role","permission","scripts","mau"],"text":"Admin Menu # The features like managing Roles and Permissions, Custom Scripts and monthly active users monitoring are placed under the Admin menu (in the left navigation of GUI). These features will be discussed one by one in this section. GUI Access Control # The administrator can control view/edit/delete access of users of Gluu Flex Admin UI by adding or removing the appropriate Permissions mapped to the user's Admin UI Role. For e.g. if the read Permission of OIDC clients ( https://jans.io/oauth/config/clients.readonly ) is not mapped to the logged-in user's Role, the contents of the page showing OIDC client records will not be visible to the user. In the same way, if the write and delete Permissions of OIDC clients are not mapped then the user will not be able to edit or delete any OIDC client record. Role # The logged-in administrator can create, edit or delete Admin UI Roles using the Admin UI Roles Page. The Admin UI Role can be assigned to the user using the User Management feature of this GUI. After installation, the following Admin UI Roles can be seen on Admin UI: api-viewer, api-editor, api-manager and api-admin. The default user i.e. admin is assigned with api-admin role. A user with one or more Admin UI Role(s) assigned will be able to log into Gluu Flex Admin UI. Permissions (Scopes) # Gluu Flex Admin UI uses Config API to manage and configure the Jans Auth server. Config API helps in configuring auth-server, users, fido2 and scim modules. The APIs of this rest application are protected using an authorization token containing the appropriate permissions (scopes). The user interface has the capability to add, edit and delete the Permissions used to access the APIs (i.e. rest APIs used by Admin UI). Role-Permission Mapping # The administrator can map the Admin UI Role with one or more Permission(s) using the Role-Permission Mapping page. The Role mapped with Permissions can be then assigned to the user to allow access to the corresponding operations of the GUI. The below table lists the Permissions used in Admin UI: Permission Description https://jans.io/oauth/config/attributes.readonly View Person attributes https://jans.io/oauth/config/attributes.write Add/Edit Person attributes https://jans.io/oauth/config/attributes.delete Delete Person attributes https://jans.io/oauth/config/scopes.readonly View the Scopes https://jans.io/oauth/config/scopes.write Add/Edit Scopes https://jans.io/oauth/config/scopes.delete Delete Scopes https://jans.io/oauth/config/scripts.readonly View the Scripts https://jans.io/oauth/config/scripts.write Add/Edit Scripts https://jans.io/oauth/config/scripts.delete Delete Scripts https://jans.io/oauth/config/openid/clients.readonly View the Clients https://jans.io/oauth/config/openid/clients.write Add/Edit Clients https://jans.io/oauth/config/openid/clients.delete Delete Clients https://jans.io/oauth/config/smtp.readonly View SMTP configuration https://jans.io/oauth/config/smtp.write Edit SMTP configuration https://jans.io/oauth/config/smtp.delete Remove SMTP configuration https://jans.io/oauth/config/logging.readonly View Auth server log configuration https://jans.io/oauth/config/logging.write Edit Auth server log configuration https://jans.io/oauth/config/database/ldap.readonly View LDAP persistence configuration https://jans.io/oauth/config/database/ldap.write Edit LDAP persistence configuration https://jans.io/oauth/config/database/ldap.delete Delete LDAP persistence configuration https://jans.io/oauth/config/jwks.readonly View JWKS https://jans.io/oauth/jans-auth-server/config/adminui/user/role.readonly View Admin UI Roles https://jans.io/oauth/jans-auth-server/config/adminui/user/role.write Edit Admin UI Roles https://jans.io/oauth/jans-auth-server/config/adminui/user/role.delete Delete Admin UI Roles https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.readonly View Admin UI Permissions https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.write Edit Admin UI Permissions https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.delete Delete Admin UI Permissions https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.readonly View Role-Permission Mapping https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.write Edit Role-Permission Mapping https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.delete Delete Role-Permission Mapping Custom Scripts # Custom Scripts are used to implement custom business logic for authentication, authorization, client registration, cache refresh, scopes, token revocation etc. The Janssen Authentication Server leverages Custom Scripts when implemented can facilitate complex business workflows without changing the server code. Gluu Flex Admin UI provides the interface to add/edit/delete custom scripts. Custom Scripts fields descriptions # INUM: Unique id identifying the script. Name: Name of the custom script. Only letters, digits and underscores are allowed. Description: Description of the script. Select SAML ACRS: The SAML parameter Authentication Context Requests (ACRS). Script Type: The type of the script (e.g. PERSON_AUTHENTICATION, INTROSPECTION, APPLICATION_SESSION, CLIENT_REGISTRATION etc). Programming Language: Programming language of the custom script (e.g. Java and Jython). Location Type: The location of the script, either database or file. Level: The level describes how secure and reliable the script is. Custom properties (key/value): Custom properties that can be used in the script. Script: Script content. Enable: Field set to enable or disable the script. MAU Graph # This is a line graph showing month-wise active users under a selected date range. Webhooks # Webhooks can be created and mapped to various Admin UI features to execute custom business logic when events associated with those features occur. Follow this tutorial for more details. Settings # The Gluu Flex Admin UI provides a user-friendly interface for managing various UI settings of this web application. This page has the following fields. List paging size: This field allows to define the default paging size for all search pages within the Admin UI. Config API URL: The read-only URL of the Jans Config API is used by the Admin UI for interaction. Admin UI Session Timeout (In Minutes): This field determines the maximum idle time allowed before a user is automatically logged out of the Admin UI. Admin UI authentication method (ACR): This dropdown enables user to select the default authentication method to be used in the Admin UI. Custom Parameters (for authentication): The custom parameters allow you to pass additional information to the authorization server during Admin UI authentication.","title":"Admin"},{"location":"admin/admin-ui/admin-menu/#admin-menu","text":"The features like managing Roles and Permissions, Custom Scripts and monthly active users monitoring are placed under the Admin menu (in the left navigation of GUI). These features will be discussed one by one in this section.","title":"Admin Menu"},{"location":"admin/admin-ui/admin-menu/#gui-access-control","text":"The administrator can control view/edit/delete access of users of Gluu Flex Admin UI by adding or removing the appropriate Permissions mapped to the user's Admin UI Role. For e.g. if the read Permission of OIDC clients ( https://jans.io/oauth/config/clients.readonly ) is not mapped to the logged-in user's Role, the contents of the page showing OIDC client records will not be visible to the user. In the same way, if the write and delete Permissions of OIDC clients are not mapped then the user will not be able to edit or delete any OIDC client record.","title":"GUI Access Control"},{"location":"admin/admin-ui/admin-menu/#role","text":"The logged-in administrator can create, edit or delete Admin UI Roles using the Admin UI Roles Page. The Admin UI Role can be assigned to the user using the User Management feature of this GUI. After installation, the following Admin UI Roles can be seen on Admin UI: api-viewer, api-editor, api-manager and api-admin. The default user i.e. admin is assigned with api-admin role. A user with one or more Admin UI Role(s) assigned will be able to log into Gluu Flex Admin UI.","title":"Role"},{"location":"admin/admin-ui/admin-menu/#permissions-scopes","text":"Gluu Flex Admin UI uses Config API to manage and configure the Jans Auth server. Config API helps in configuring auth-server, users, fido2 and scim modules. The APIs of this rest application are protected using an authorization token containing the appropriate permissions (scopes). The user interface has the capability to add, edit and delete the Permissions used to access the APIs (i.e. rest APIs used by Admin UI).","title":"Permissions (Scopes)"},{"location":"admin/admin-ui/admin-menu/#role-permission-mapping","text":"The administrator can map the Admin UI Role with one or more Permission(s) using the Role-Permission Mapping page. The Role mapped with Permissions can be then assigned to the user to allow access to the corresponding operations of the GUI. The below table lists the Permissions used in Admin UI: Permission Description https://jans.io/oauth/config/attributes.readonly View Person attributes https://jans.io/oauth/config/attributes.write Add/Edit Person attributes https://jans.io/oauth/config/attributes.delete Delete Person attributes https://jans.io/oauth/config/scopes.readonly View the Scopes https://jans.io/oauth/config/scopes.write Add/Edit Scopes https://jans.io/oauth/config/scopes.delete Delete Scopes https://jans.io/oauth/config/scripts.readonly View the Scripts https://jans.io/oauth/config/scripts.write Add/Edit Scripts https://jans.io/oauth/config/scripts.delete Delete Scripts https://jans.io/oauth/config/openid/clients.readonly View the Clients https://jans.io/oauth/config/openid/clients.write Add/Edit Clients https://jans.io/oauth/config/openid/clients.delete Delete Clients https://jans.io/oauth/config/smtp.readonly View SMTP configuration https://jans.io/oauth/config/smtp.write Edit SMTP configuration https://jans.io/oauth/config/smtp.delete Remove SMTP configuration https://jans.io/oauth/config/logging.readonly View Auth server log configuration https://jans.io/oauth/config/logging.write Edit Auth server log configuration https://jans.io/oauth/config/database/ldap.readonly View LDAP persistence configuration https://jans.io/oauth/config/database/ldap.write Edit LDAP persistence configuration https://jans.io/oauth/config/database/ldap.delete Delete LDAP persistence configuration https://jans.io/oauth/config/jwks.readonly View JWKS https://jans.io/oauth/jans-auth-server/config/adminui/user/role.readonly View Admin UI Roles https://jans.io/oauth/jans-auth-server/config/adminui/user/role.write Edit Admin UI Roles https://jans.io/oauth/jans-auth-server/config/adminui/user/role.delete Delete Admin UI Roles https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.readonly View Admin UI Permissions https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.write Edit Admin UI Permissions https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.delete Delete Admin UI Permissions https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.readonly View Role-Permission Mapping https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.write Edit Role-Permission Mapping https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.delete Delete Role-Permission Mapping","title":"Role-Permission Mapping"},{"location":"admin/admin-ui/admin-menu/#custom-scripts","text":"Custom Scripts are used to implement custom business logic for authentication, authorization, client registration, cache refresh, scopes, token revocation etc. The Janssen Authentication Server leverages Custom Scripts when implemented can facilitate complex business workflows without changing the server code. Gluu Flex Admin UI provides the interface to add/edit/delete custom scripts.","title":"Custom Scripts"},{"location":"admin/admin-ui/admin-menu/#custom-scripts-fields-descriptions","text":"INUM: Unique id identifying the script. Name: Name of the custom script. Only letters, digits and underscores are allowed. Description: Description of the script. Select SAML ACRS: The SAML parameter Authentication Context Requests (ACRS). Script Type: The type of the script (e.g. PERSON_AUTHENTICATION, INTROSPECTION, APPLICATION_SESSION, CLIENT_REGISTRATION etc). Programming Language: Programming language of the custom script (e.g. Java and Jython). Location Type: The location of the script, either database or file. Level: The level describes how secure and reliable the script is. Custom properties (key/value): Custom properties that can be used in the script. Script: Script content. Enable: Field set to enable or disable the script.","title":"Custom Scripts fields descriptions"},{"location":"admin/admin-ui/admin-menu/#mau-graph","text":"This is a line graph showing month-wise active users under a selected date range.","title":"MAU Graph"},{"location":"admin/admin-ui/admin-menu/#webhooks","text":"Webhooks can be created and mapped to various Admin UI features to execute custom business logic when events associated with those features occur. Follow this tutorial for more details.","title":"Webhooks"},{"location":"admin/admin-ui/admin-menu/#settings","text":"The Gluu Flex Admin UI provides a user-friendly interface for managing various UI settings of this web application. This page has the following fields. List paging size: This field allows to define the default paging size for all search pages within the Admin UI. Config API URL: The read-only URL of the Jans Config API is used by the Admin UI for interaction. Admin UI Session Timeout (In Minutes): This field determines the maximum idle time allowed before a user is automatically logged out of the Admin UI. Admin UI authentication method (ACR): This dropdown enables user to select the default authentication method to be used in the Admin UI. Custom Parameters (for authentication): The custom parameters allow you to pass additional information to the authorization server during Admin UI authentication.","title":"Settings"},{"location":"admin/admin-ui/auth-server-interaction/","tags":["administration","admin-ui","interaction"],"text":"Interaction with Jans Auth Server # This user-friendly interface facilitates interaction with the Jans Auth Server through a REST API layer known as the Jans Config API . Here, we'll explore the working mechanism of the Gluu Flex Admin UI, focusing on its interaction with the Jans Auth Server and the key steps involved. When accessing the Gluu Flex Admin UI through a web browser, the following steps are involved: License Verification # The user accesses the Gluu Flex Admin UI frontend through a web browser. The frontend requests the Admin UI backend to retrieve Admin UI configuration from Janssen persistence. The Admin UI configuration includes OIDC client details for accessing the Auth Server, OIDC client details for accessing the Token Server, OIDC client details for accessing the License APIs, and license metadata. It's important to note that the Admin UI backend is implemented as a Jans Config API plugin . The frontend calls the Admin UI backend API ( /isConfigValid ) to validate the license configuration in persistence, essentially verifying the validity of the OIDC client used to access the License APIs. If it is not valid, the same API tries to register a new OIDC client using the SSA uploaded during installation. In case the SSA is invalid, the Admin UI shows a page to upload a new valid SSA. After ensuring the validity of the OIDC client, the Admin UI calls the Admin UI backend API (/isActive) to check if a valid license is present in the license configuration. The Admin UI backend then calls the SCAN API (/scan/license/isActive) to verify the validity of the license. If a valid license is not present, the frontend calls the backend API (/retrieve) to retrieve the license for the user via the SCAN API (/scan/license/retrieve). The license can only be retrieved from SCAN if the user has subscribed to the Admin UI license in Agama Lab. If the user has not already subscribed to a valid license in Agama Lab, the Admin UI displays a page to generate a 30-day trial license. The user cannot generate another trial license after expiry of a generated trial license and will need to subscribe to the Admin UI license in Agama Lab to access the user interface. After verification of valid license the frontend initiates the Authorization Code Flow by redirecting the user to the login page. sequenceDiagram title License Verification autonumber actor User User->>Browser: open Admin UI URL Browser->>Gluu Flex Admin UI: launch Admin UI Gluu Flex Admin UI->>Admin UI Backend: /config Admin UI Backend->>Gluu Flex Admin UI: Admin UI config Gluu Flex Admin UI->>Admin UI Backend: /license/isConfigValid Note over Gluu Flex Admin UI,Admin UI Backend: validate license OIDC client alt license client valid Admin UI Backend->>Gluu Flex Admin UI: true else license client invalid Admin UI Backend->>account.gluu.org: DCR using SSA alt DCR success account.gluu.org->>Admin UI Backend: client credentials Admin UI Backend->>Admin UI Backend: save client credentials in persistence Admin UI Backend->>Gluu Flex Admin UI: true else DCR fails Admin UI Backend->>Gluu Flex Admin UI: false Gluu Flex Admin UI->>Browser: Screen to Upload SSA end end Gluu Flex Admin UI->>Admin UI Backend: /license/isActive Note over Gluu Flex Admin UI,Admin UI Backend: validate license Admin UI Backend->>SCAN: /scan/license/isActive alt license active SCAN->>Admin UI Backend: true else license inactive / not present SCAN->>Admin UI Backend: false Admin UI Backend->>SCAN: /retrieve alt license subscribed SCAN->>Admin UI Backend: license else license not subscribed SCAN->>Admin UI Backend: false Admin UI Backend->>Gluu Flex Admin UI: false Gluu Flex Admin UI->>Browser: Screen to generate Trial license end end Admin UI Backend->>Gluu Flex Admin UI: login page The Authorization Code Flow # The frontend initiates the Authorization Code Flow by calling authorization url and redirecting the user to the login page of the Janssen authorization server for user authentication. Upon successful authentication, the authorization server sends an authorization code and a state to the frontend. The frontend verifies the state. The frontend utilizes the authorization code to first obtain an access token ( AT1 ) from the token endpoint of the authorization server. With AT1, the frontend requests the User-Info in JWT format ( UJWT ) from the authorization server by calling userInfo endpoint. The frontend stores the UJWT and its claims, including the user's role ( claim name is jansAdminUIRole ) and other relevant information, in the Redux store. sequenceDiagram title License Verification autonumber actor User Gluu Flex Admin UI->>Jans Auth Server: /authorize Jans Auth Server->>Gluu Flex Admin UI:code Gluu Flex Admin UI->>Jans Auth Server: /token Note right of Gluu Flex Admin UI: code as parameter Jans Auth Server->>Gluu Flex Admin UI: access_token Note right of Gluu Flex Admin UI: access_token as parameter Gluu Flex Admin UI->>Jans Auth Server: /userInfo Jans Auth Server->>Gluu Flex Admin UI: user-info (UJWT) Gluu Flex Admin UI->>Gluu Flex Admin UI: extract & store claims from UJWT API Protection and Scopes # To ensure security and access control, Gluu Flex Admin UI leverages API protection and scopes: The Jans Config API's endpoints are protected and can only be accessed using a token ( AT2 ) with the required scopes. To generate an AT2, the frontend requests the Token Server via the backend. The Token Server and Authorization Server can be the same or different. The Token Server employs an introspection script that validates the UJWT and refers to the role-scope mapping in the Token Server persistence. The introspection script validates the UJWT and includes the appropriate scopes in AT2 based on the user's role. The frontend receives AT2 and associated scopes from the backend. Features in the frontend are enabled or disabled based on the scopes provided in AT2. Refer this doc for GUI access control. sequenceDiagram title License Verification autonumber actor User Gluu Flex Admin UI->>Admin UI Backend: /api-protection-token?ujwt=... Admin UI Backend->>Jans Token Server: /token Jans Token Server->>Jans Token Server: Verify ujwt Jans Token Server->>Jans Token Server: Add scopes to token based on role (AT2) Jans Token Server->>Admin UI Backend: AT2 Admin UI Backend->>Gluu Flex Admin UI: AT2 Gluu Flex Admin UI->>Gluu Flex Admin UI:extracts scopes from AT2 Gluu Flex Admin UI->>Gluu Flex Admin UI: GUI access control based on scopes from AT2 Accessing Config-API Endpoints # To access config-api endpoints, the following steps are taken: The Admin UI frontend requests AT2 from the Token Server through the backend. Armed with AT2, the frontend sends a request to the desired Jans Config API endpoint. AT2 is included in the authorization header, along with other request parameters. At the Jans Config API, AT2 is validated, and the provided scopes are verified to ensure the necessary scope for the requested endpoint is present. If the above steps are successful, the requested data is fetched from the Jans Config API and forwarded to the frontend. sequenceDiagram title License Verification autonumber actor User Gluu Flex Admin UI->>Admin UI Backend: /api-protection-token?ujwt=... Admin UI Backend->>Jans Token Server: /token Jans Token Server->>Jans Token Server: Verify ujwt Jans Token Server->>Jans Token Server: Add scopes to token based on role (AT2) Jans Token Server->>Admin UI Backend: AT2 Admin UI Backend->>Gluu Flex Admin UI: AT2 Gluu Flex Admin UI->>Jans Config API: request API with AT2 Jans Config API<<->>Jans Token Server: introspect AT2 Jans Token Server->>Jans Config API: AT2 JSON Jans Config API->>Jans Config API: Enforcement: verify required scopes Jans Config API->>Jans Config API: validate params Jans Config API->>Jans Auth Server:call API with request params Jans Auth Server->>Jans Config API:response Jans Config API->>Gluu Flex Admin UI:response Conclusion # The Gluu Flex Admin UI simplifies the process of managing configuration and features of the Jans Auth Server through an intuitive graphical user interface. By following the Authorization Code Flow and leveraging API protection and scopes, the Gluu Flex Admin UI ensures secure and controlled interaction with the Jans Auth Server's REST API layer. This seamless interaction empowers administrators to efficiently manage the Jans Auth Server's settings while adhering to strict access controls and security protocols.","title":"Auth Server Interaction"},{"location":"admin/admin-ui/auth-server-interaction/#interaction-with-jans-auth-server","text":"This user-friendly interface facilitates interaction with the Jans Auth Server through a REST API layer known as the Jans Config API . Here, we'll explore the working mechanism of the Gluu Flex Admin UI, focusing on its interaction with the Jans Auth Server and the key steps involved. When accessing the Gluu Flex Admin UI through a web browser, the following steps are involved:","title":"Interaction with Jans Auth Server"},{"location":"admin/admin-ui/auth-server-interaction/#license-verification","text":"The user accesses the Gluu Flex Admin UI frontend through a web browser. The frontend requests the Admin UI backend to retrieve Admin UI configuration from Janssen persistence. The Admin UI configuration includes OIDC client details for accessing the Auth Server, OIDC client details for accessing the Token Server, OIDC client details for accessing the License APIs, and license metadata. It's important to note that the Admin UI backend is implemented as a Jans Config API plugin . The frontend calls the Admin UI backend API ( /isConfigValid ) to validate the license configuration in persistence, essentially verifying the validity of the OIDC client used to access the License APIs. If it is not valid, the same API tries to register a new OIDC client using the SSA uploaded during installation. In case the SSA is invalid, the Admin UI shows a page to upload a new valid SSA. After ensuring the validity of the OIDC client, the Admin UI calls the Admin UI backend API (/isActive) to check if a valid license is present in the license configuration. The Admin UI backend then calls the SCAN API (/scan/license/isActive) to verify the validity of the license. If a valid license is not present, the frontend calls the backend API (/retrieve) to retrieve the license for the user via the SCAN API (/scan/license/retrieve). The license can only be retrieved from SCAN if the user has subscribed to the Admin UI license in Agama Lab. If the user has not already subscribed to a valid license in Agama Lab, the Admin UI displays a page to generate a 30-day trial license. The user cannot generate another trial license after expiry of a generated trial license and will need to subscribe to the Admin UI license in Agama Lab to access the user interface. After verification of valid license the frontend initiates the Authorization Code Flow by redirecting the user to the login page. sequenceDiagram title License Verification autonumber actor User User->>Browser: open Admin UI URL Browser->>Gluu Flex Admin UI: launch Admin UI Gluu Flex Admin UI->>Admin UI Backend: /config Admin UI Backend->>Gluu Flex Admin UI: Admin UI config Gluu Flex Admin UI->>Admin UI Backend: /license/isConfigValid Note over Gluu Flex Admin UI,Admin UI Backend: validate license OIDC client alt license client valid Admin UI Backend->>Gluu Flex Admin UI: true else license client invalid Admin UI Backend->>account.gluu.org: DCR using SSA alt DCR success account.gluu.org->>Admin UI Backend: client credentials Admin UI Backend->>Admin UI Backend: save client credentials in persistence Admin UI Backend->>Gluu Flex Admin UI: true else DCR fails Admin UI Backend->>Gluu Flex Admin UI: false Gluu Flex Admin UI->>Browser: Screen to Upload SSA end end Gluu Flex Admin UI->>Admin UI Backend: /license/isActive Note over Gluu Flex Admin UI,Admin UI Backend: validate license Admin UI Backend->>SCAN: /scan/license/isActive alt license active SCAN->>Admin UI Backend: true else license inactive / not present SCAN->>Admin UI Backend: false Admin UI Backend->>SCAN: /retrieve alt license subscribed SCAN->>Admin UI Backend: license else license not subscribed SCAN->>Admin UI Backend: false Admin UI Backend->>Gluu Flex Admin UI: false Gluu Flex Admin UI->>Browser: Screen to generate Trial license end end Admin UI Backend->>Gluu Flex Admin UI: login page","title":"License Verification"},{"location":"admin/admin-ui/auth-server-interaction/#the-authorization-code-flow","text":"The frontend initiates the Authorization Code Flow by calling authorization url and redirecting the user to the login page of the Janssen authorization server for user authentication. Upon successful authentication, the authorization server sends an authorization code and a state to the frontend. The frontend verifies the state. The frontend utilizes the authorization code to first obtain an access token ( AT1 ) from the token endpoint of the authorization server. With AT1, the frontend requests the User-Info in JWT format ( UJWT ) from the authorization server by calling userInfo endpoint. The frontend stores the UJWT and its claims, including the user's role ( claim name is jansAdminUIRole ) and other relevant information, in the Redux store. sequenceDiagram title License Verification autonumber actor User Gluu Flex Admin UI->>Jans Auth Server: /authorize Jans Auth Server->>Gluu Flex Admin UI:code Gluu Flex Admin UI->>Jans Auth Server: /token Note right of Gluu Flex Admin UI: code as parameter Jans Auth Server->>Gluu Flex Admin UI: access_token Note right of Gluu Flex Admin UI: access_token as parameter Gluu Flex Admin UI->>Jans Auth Server: /userInfo Jans Auth Server->>Gluu Flex Admin UI: user-info (UJWT) Gluu Flex Admin UI->>Gluu Flex Admin UI: extract & store claims from UJWT","title":"The Authorization Code Flow"},{"location":"admin/admin-ui/auth-server-interaction/#api-protection-and-scopes","text":"To ensure security and access control, Gluu Flex Admin UI leverages API protection and scopes: The Jans Config API's endpoints are protected and can only be accessed using a token ( AT2 ) with the required scopes. To generate an AT2, the frontend requests the Token Server via the backend. The Token Server and Authorization Server can be the same or different. The Token Server employs an introspection script that validates the UJWT and refers to the role-scope mapping in the Token Server persistence. The introspection script validates the UJWT and includes the appropriate scopes in AT2 based on the user's role. The frontend receives AT2 and associated scopes from the backend. Features in the frontend are enabled or disabled based on the scopes provided in AT2. Refer this doc for GUI access control. sequenceDiagram title License Verification autonumber actor User Gluu Flex Admin UI->>Admin UI Backend: /api-protection-token?ujwt=... Admin UI Backend->>Jans Token Server: /token Jans Token Server->>Jans Token Server: Verify ujwt Jans Token Server->>Jans Token Server: Add scopes to token based on role (AT2) Jans Token Server->>Admin UI Backend: AT2 Admin UI Backend->>Gluu Flex Admin UI: AT2 Gluu Flex Admin UI->>Gluu Flex Admin UI:extracts scopes from AT2 Gluu Flex Admin UI->>Gluu Flex Admin UI: GUI access control based on scopes from AT2","title":"API Protection and Scopes"},{"location":"admin/admin-ui/auth-server-interaction/#accessing-config-api-endpoints","text":"To access config-api endpoints, the following steps are taken: The Admin UI frontend requests AT2 from the Token Server through the backend. Armed with AT2, the frontend sends a request to the desired Jans Config API endpoint. AT2 is included in the authorization header, along with other request parameters. At the Jans Config API, AT2 is validated, and the provided scopes are verified to ensure the necessary scope for the requested endpoint is present. If the above steps are successful, the requested data is fetched from the Jans Config API and forwarded to the frontend. sequenceDiagram title License Verification autonumber actor User Gluu Flex Admin UI->>Admin UI Backend: /api-protection-token?ujwt=... Admin UI Backend->>Jans Token Server: /token Jans Token Server->>Jans Token Server: Verify ujwt Jans Token Server->>Jans Token Server: Add scopes to token based on role (AT2) Jans Token Server->>Admin UI Backend: AT2 Admin UI Backend->>Gluu Flex Admin UI: AT2 Gluu Flex Admin UI->>Jans Config API: request API with AT2 Jans Config API<<->>Jans Token Server: introspect AT2 Jans Token Server->>Jans Config API: AT2 JSON Jans Config API->>Jans Config API: Enforcement: verify required scopes Jans Config API->>Jans Config API: validate params Jans Config API->>Jans Auth Server:call API with request params Jans Auth Server->>Jans Config API:response Jans Config API->>Gluu Flex Admin UI:response","title":"Accessing Config-API Endpoints"},{"location":"admin/admin-ui/auth-server-interaction/#conclusion","text":"The Gluu Flex Admin UI simplifies the process of managing configuration and features of the Jans Auth Server through an intuitive graphical user interface. By following the Authorization Code Flow and leveraging API protection and scopes, the Gluu Flex Admin UI ensures secure and controlled interaction with the Jans Auth Server's REST API layer. This seamless interaction empowers administrators to efficiently manage the Jans Auth Server's settings while adhering to strict access controls and security protocols.","title":"Conclusion"},{"location":"admin/admin-ui/auth-server-menu/","tags":["administration","admin-ui","auth server","sessions","configuration","keys","logging","clients","scopes"],"text":"Auth Server Menu # The Auth Server menu covers the following important sub-menus to configure and manage Auth server. Sessions Server configuration Keys Logging Clients Scopes Enabled Acrs Agama deployment Sessions # The Janssen Authentication Server stores user session data in persistence. This screen lists the active session details and the administrator can revoke the sessions of the selected user. Keys # The JSON Web Key Sets (JWKS) is a set of public keys that should be used to verify any JSON Web Token (JWT) issued by the authorization server. Auth Server Configuration Properties # The auth server configuration properties can be updated using GUI. Logging # Following AS configuration properties can be used to customize AS logging: Log level: Specify the log levels of loggers Log layout: Logging layout used for Jans Authorization Server loggers Enable HTTP Logging: Enable/disable the request/response logging filter. Disabled by default. Disable JDK Logger?: Choose whether to disable JDK loggers Enable Oauth Audit Logging?: enable OAuth Audit Logging Clients # The logged-in user with appropriate permissions can view, register, edit and delete OIDC clients on auth server using Gluu Flex Admin UI. The Client details are as follows: Client fields Description Client name Name of the Client to be presented to the End-User. Client secret Client Secret. The same Client Secret value MUST NOT be assigned to multiple Clients. Description Description of the client. Authn method token endpoint Requested Client Authentication method for the Token Endpoint. The options are client_secret_post, client_secret_basic, client_secret_jwt, private_key_jwt, and none. Subject type Subject type requested for responses to this Client. The subject_types_supported Discovery parameter contains a list of the supported subject_type values for this server. Valid types include pairwise and public. Sector Identifier URI URL using the https scheme to be used in calculating Pseudonymous Identifiers by the OP. The URL references a file with a single JSON array of redirect_uri values. Grants List of the OAuth 2.0 Grant Types that the Client is declaring that it will restrict itself to using. Response types List of the OAuth 2.0 response_type values that the Client is declaring that it will restrict itself to using. If omitted, the default is that the Client will use only the code Response Type. Active Specifies whether the client is enabled. Application type Kind of the application. The default, if omitted, is web. Redirect URIs List of Redirection URI values used by the Client. One of these registered Redirection URI values MUST exactly match the redirect_uri parameter value used in each Authorization Request Redirect Regex When this field is set then redirect-URI must match with regex. Scopes List of scopes granted to the client. Access token type Type of the access token (JWT or reference) generated by the client. Include claims in id_token The claims will be included in id_token if this field is enabled Add auth_time to id_token When enabled then the auth_time claim is required in id_token. Run Introspection Script Before AccessToken As Jwt Creation And Include Claims When this field is enabled then Introspection Script will run before access token generation. Token binding confirmation method for id_token Specifies the JWT Confirmation Method member name (e.g. tbh) that the Relying Party expects when receiving Token Bound ID Tokens. The presence of this parameter indicates that the Relying Party supports the Token Binding of ID Tokens. If omitted, the default is that the Relying Party does not support the Token Binding of ID Tokens. Access token additional audiences The client audiences. Access token lifetime The client-specific access-token expiration. Refresh token lifetime The client-specific refresh-token expiration. Default max authn age The default maximum authentication age. Front channel. logout URI Relying Party (RP) URL that will cause the RP to log itself out when rendered in an iframe by the OP. This is used in the front-channel logout mechanisms, which communicate logout requests from the OP to RPs via the User Agent. Post logout redirect URI Provide the URLs supplied by the RP to request that the user be redirected to this location after a logout has been performed. Back channel. logout URI Relying Party (RP) URL that will cause the RP to log itself out when sent a Logout Token by the OP. This is used in the back-channel logout mechanisms, which communicate logout requests directly between the OP and RPs. Back channel. logout session required Boolean value specifying whether the RP requires that a sid (session ID) Claim be included in the Logout Token to identify the RP session with the OP when the backchannel_logout_uri is used. Front channel. logout session required Boolean value specifying whether the RP requires that iss (issuer) and sid (session ID) query parameters be included to identify the RP session with the OP when the frontchannel_logout_uri is used. Client URI URL of the home page of the Client. The value of this field must point to a valid Web page. Policy URI URL that the Relying Party Client provides to the End-User to read about how the profile data will be used. Logo URI URL that references a logo for the Client application. Terms of service URI URL that the Relying Party Client provides to the End-User to read about the Relying Party's terms of service. Contacts OpenID connect client contacts list. Authorized JS origins Specifies authorized JavaScript origins. Software id Specifies a unique identifier string (UUID) assigned by the client developer or software publisher used by registration endpoints to identify the client software to be dynamically registered. Software version Specifies a version identifier string for the client software identified by 'software_id'. The value of the 'software_version' should change on any update to the client software identified by the same 'software_id'. Software statement Specifies a software statement containing client metadata values about the client software as claims. This is a string value containing the entire signed JWT. CIBA: Token delivery method Specifies how backchannel token will be delivered. CIBA: Client notification endpoint Client Initiated Backchannel Authentication (CIBA) enables a Client to initiate the authentication of an end-user by means of out-of-band mechanisms. Upon receipt of the notification, the Client makes a request to the token endpoint to obtain the tokens. CIBA: Require user code param If selected the auth_time claim is included in id_token. PAR: Require lifetime Represents the lifetime of Pushed Authorisation Request (PAR). PAR: Require PAR Is Pushed Authorisation Request (PAR) required? UMA: RPT token type Type of RPT token (JWT or reference). UMA: Claims redirect URI Array of The Claims Redirect URIs to which the client wishes the authorization server to direct the requesting party's user agent after completing its interaction. UMA: RPT Modification Script List of Requesting Party Token (RPT) claims scripts. Client JWKS URI URL for the Client's JSON Web Key Set (JWK) document containing the key(s) that are used for signing requests to the OP. The JWK Set may also contain the Client''s encryption keys(s) that are used by the OP to encrypt the responses to the Client. When both signing and encryption keys are made available, a use (Key Use) parameter value is required for all keys in the document to indicate each key's intended usage. Client JWKS List of JSON Web Key (JWK) - A JSON object that represents a cryptographic key. The members of the object represent properties of the key, including its value. id_token subject type The subject identifiers in ID tokens. Persist Authorizations Specifies if the client authorization details are to be persisted. The default value is true. Allow spontaneous scopes Whether to allow spontaneous scopes for the client. Spontaneous scope validation regex List of spontaneous scope regular expression. Spontaneous scopes Spontaneous scopes created using the client. Initiate Login URI Specifies the URI using the https scheme that the authorization server can call to initiate a login at the client. Request URIs Provide a list of requests_uri values that are pre-registered by the Client for use at the Authorization Server. Default ACR Array of default requested Authentication Context Class Reference values that the Authorization Server must use for processing requests from the Client. Allowed ACRs Allowed ACRs Default prompt=login If enabled then sets prompt=login to the authorization request, which causes the authorization server to force the user to sign in again before it will show the authorization prompt. TLS Subject DN String representation of the expected subject distinguished name of the certificate, which the OAuth client will use in mutual TLS authentication. Is Expirable Client? Specifies whether client is expirable Client Scripts The custom scripts specific to the client. Scopes # The scope is a mechanism to limit an application's access to a user's account. An application can request one or more scopes, this information is then presented to the user in the consent screen, and the access token issued to the application will be limited to the scopes granted. Please check here for detail documentation on scopes. OAuth 2.0 scopes # This scope type would only have a description, but no claims. Once a client obtains this token, it may be passed to the backend API. OpenID scopes # Specify what access privileges are being requested for Access Tokens. The scopes associated with Access Tokens determine what resources will be available when they are used to access OAuth 2.0 protected endpoints. For OpenID Connect, scopes can be used to request that specific sets of information be made available as Claim Values. Spontaneous scopes # Spontaneous scopes are scopes with random part in it which are not known in advance. For e.g. transaction:4685456787, pis-552fds where 4685456787 or 552fds are generated part of the scope. Spontaneous scopes are disabled by default and can be enabled per client. The admins cannot create a spontaneous scope. Creation only happens when an authorized client presents a spontaneous scope at the token endpoint. There are the following client properties available during dynamic registration of the client related to spontaneous scopes: allowSpontaneousScopes OPTIONAL, boolean, false by default. Whether spontaneous scopes are allowed for the given client. spontaneousScopes OPTIONAL, array of strings. Regular expressions which should match to scope. If matched scope is allowed. Example: [\"^transaction:.+$\"]. It matches transaction:245 but not transaction:. UMA scopes # UMA scope can either be created by the user or auto-created by the authentication server. UMA scope cannot be modified using Gluu Flex Admin UI. If the logged-in user creates UMA scope then the creator type will be USER and the creator Id will be logged-in user's INUM. If auth server has auto-created a UMA scope then it will have the creator type as AUTO and no creator Id. Dynamic Scopes # The dynamic scope custom script allows to generate a list of claims (and their values) on the fly, depending on circumstances like the id of the client requesting it, logged user's session parameters, values of other user's attributes, results of some calculations implementing specific business logic and/or requests to remote APIs or databases. Claims are then returned the usual way in response to a call to the user info endpoint. In order to configure a dynamic scope the following steps are required: The script of type DYNAMIC_SCOPE must be configured and enabled. Create scope of scope type Dynamic and select Dynamic scope script and claims inputs. Authn # Authentication Context Class Reference (ACR) enables applications to request and verify the level of authentication assurance or the context of the authentication process used for user authentication. This page allows the administrator to view all enabled ACRs and select the default ACR which refers to the predefined or default authentication assurance when no specific ACR value is requested or specified. Agama # This menu addresses deployment of Agama project packages (file with .gama extension). To make sure that package is untempered, the file containing sha256 checksum also need to be uploaded on UI. The project name, description, version, deployment start/end date-time and deployment error (if any) can be seen on details popup of the record. User can export sample and current configuration or import configuration.","title":"Auth server"},{"location":"admin/admin-ui/auth-server-menu/#auth-server-menu","text":"The Auth Server menu covers the following important sub-menus to configure and manage Auth server. Sessions Server configuration Keys Logging Clients Scopes Enabled Acrs Agama deployment","title":"Auth Server Menu"},{"location":"admin/admin-ui/auth-server-menu/#sessions","text":"The Janssen Authentication Server stores user session data in persistence. This screen lists the active session details and the administrator can revoke the sessions of the selected user.","title":"Sessions"},{"location":"admin/admin-ui/auth-server-menu/#keys","text":"The JSON Web Key Sets (JWKS) is a set of public keys that should be used to verify any JSON Web Token (JWT) issued by the authorization server.","title":"Keys"},{"location":"admin/admin-ui/auth-server-menu/#auth-server-configuration-properties","text":"The auth server configuration properties can be updated using GUI.","title":"Auth Server Configuration Properties"},{"location":"admin/admin-ui/auth-server-menu/#logging","text":"Following AS configuration properties can be used to customize AS logging: Log level: Specify the log levels of loggers Log layout: Logging layout used for Jans Authorization Server loggers Enable HTTP Logging: Enable/disable the request/response logging filter. Disabled by default. Disable JDK Logger?: Choose whether to disable JDK loggers Enable Oauth Audit Logging?: enable OAuth Audit Logging","title":"Logging"},{"location":"admin/admin-ui/auth-server-menu/#clients","text":"The logged-in user with appropriate permissions can view, register, edit and delete OIDC clients on auth server using Gluu Flex Admin UI. The Client details are as follows: Client fields Description Client name Name of the Client to be presented to the End-User. Client secret Client Secret. The same Client Secret value MUST NOT be assigned to multiple Clients. Description Description of the client. Authn method token endpoint Requested Client Authentication method for the Token Endpoint. The options are client_secret_post, client_secret_basic, client_secret_jwt, private_key_jwt, and none. Subject type Subject type requested for responses to this Client. The subject_types_supported Discovery parameter contains a list of the supported subject_type values for this server. Valid types include pairwise and public. Sector Identifier URI URL using the https scheme to be used in calculating Pseudonymous Identifiers by the OP. The URL references a file with a single JSON array of redirect_uri values. Grants List of the OAuth 2.0 Grant Types that the Client is declaring that it will restrict itself to using. Response types List of the OAuth 2.0 response_type values that the Client is declaring that it will restrict itself to using. If omitted, the default is that the Client will use only the code Response Type. Active Specifies whether the client is enabled. Application type Kind of the application. The default, if omitted, is web. Redirect URIs List of Redirection URI values used by the Client. One of these registered Redirection URI values MUST exactly match the redirect_uri parameter value used in each Authorization Request Redirect Regex When this field is set then redirect-URI must match with regex. Scopes List of scopes granted to the client. Access token type Type of the access token (JWT or reference) generated by the client. Include claims in id_token The claims will be included in id_token if this field is enabled Add auth_time to id_token When enabled then the auth_time claim is required in id_token. Run Introspection Script Before AccessToken As Jwt Creation And Include Claims When this field is enabled then Introspection Script will run before access token generation. Token binding confirmation method for id_token Specifies the JWT Confirmation Method member name (e.g. tbh) that the Relying Party expects when receiving Token Bound ID Tokens. The presence of this parameter indicates that the Relying Party supports the Token Binding of ID Tokens. If omitted, the default is that the Relying Party does not support the Token Binding of ID Tokens. Access token additional audiences The client audiences. Access token lifetime The client-specific access-token expiration. Refresh token lifetime The client-specific refresh-token expiration. Default max authn age The default maximum authentication age. Front channel. logout URI Relying Party (RP) URL that will cause the RP to log itself out when rendered in an iframe by the OP. This is used in the front-channel logout mechanisms, which communicate logout requests from the OP to RPs via the User Agent. Post logout redirect URI Provide the URLs supplied by the RP to request that the user be redirected to this location after a logout has been performed. Back channel. logout URI Relying Party (RP) URL that will cause the RP to log itself out when sent a Logout Token by the OP. This is used in the back-channel logout mechanisms, which communicate logout requests directly between the OP and RPs. Back channel. logout session required Boolean value specifying whether the RP requires that a sid (session ID) Claim be included in the Logout Token to identify the RP session with the OP when the backchannel_logout_uri is used. Front channel. logout session required Boolean value specifying whether the RP requires that iss (issuer) and sid (session ID) query parameters be included to identify the RP session with the OP when the frontchannel_logout_uri is used. Client URI URL of the home page of the Client. The value of this field must point to a valid Web page. Policy URI URL that the Relying Party Client provides to the End-User to read about how the profile data will be used. Logo URI URL that references a logo for the Client application. Terms of service URI URL that the Relying Party Client provides to the End-User to read about the Relying Party's terms of service. Contacts OpenID connect client contacts list. Authorized JS origins Specifies authorized JavaScript origins. Software id Specifies a unique identifier string (UUID) assigned by the client developer or software publisher used by registration endpoints to identify the client software to be dynamically registered. Software version Specifies a version identifier string for the client software identified by 'software_id'. The value of the 'software_version' should change on any update to the client software identified by the same 'software_id'. Software statement Specifies a software statement containing client metadata values about the client software as claims. This is a string value containing the entire signed JWT. CIBA: Token delivery method Specifies how backchannel token will be delivered. CIBA: Client notification endpoint Client Initiated Backchannel Authentication (CIBA) enables a Client to initiate the authentication of an end-user by means of out-of-band mechanisms. Upon receipt of the notification, the Client makes a request to the token endpoint to obtain the tokens. CIBA: Require user code param If selected the auth_time claim is included in id_token. PAR: Require lifetime Represents the lifetime of Pushed Authorisation Request (PAR). PAR: Require PAR Is Pushed Authorisation Request (PAR) required? UMA: RPT token type Type of RPT token (JWT or reference). UMA: Claims redirect URI Array of The Claims Redirect URIs to which the client wishes the authorization server to direct the requesting party's user agent after completing its interaction. UMA: RPT Modification Script List of Requesting Party Token (RPT) claims scripts. Client JWKS URI URL for the Client's JSON Web Key Set (JWK) document containing the key(s) that are used for signing requests to the OP. The JWK Set may also contain the Client''s encryption keys(s) that are used by the OP to encrypt the responses to the Client. When both signing and encryption keys are made available, a use (Key Use) parameter value is required for all keys in the document to indicate each key's intended usage. Client JWKS List of JSON Web Key (JWK) - A JSON object that represents a cryptographic key. The members of the object represent properties of the key, including its value. id_token subject type The subject identifiers in ID tokens. Persist Authorizations Specifies if the client authorization details are to be persisted. The default value is true. Allow spontaneous scopes Whether to allow spontaneous scopes for the client. Spontaneous scope validation regex List of spontaneous scope regular expression. Spontaneous scopes Spontaneous scopes created using the client. Initiate Login URI Specifies the URI using the https scheme that the authorization server can call to initiate a login at the client. Request URIs Provide a list of requests_uri values that are pre-registered by the Client for use at the Authorization Server. Default ACR Array of default requested Authentication Context Class Reference values that the Authorization Server must use for processing requests from the Client. Allowed ACRs Allowed ACRs Default prompt=login If enabled then sets prompt=login to the authorization request, which causes the authorization server to force the user to sign in again before it will show the authorization prompt. TLS Subject DN String representation of the expected subject distinguished name of the certificate, which the OAuth client will use in mutual TLS authentication. Is Expirable Client? Specifies whether client is expirable Client Scripts The custom scripts specific to the client.","title":"Clients"},{"location":"admin/admin-ui/auth-server-menu/#scopes","text":"The scope is a mechanism to limit an application's access to a user's account. An application can request one or more scopes, this information is then presented to the user in the consent screen, and the access token issued to the application will be limited to the scopes granted. Please check here for detail documentation on scopes.","title":"Scopes"},{"location":"admin/admin-ui/auth-server-menu/#oauth-20-scopes","text":"This scope type would only have a description, but no claims. Once a client obtains this token, it may be passed to the backend API.","title":"OAuth 2.0 scopes"},{"location":"admin/admin-ui/auth-server-menu/#openid-scopes","text":"Specify what access privileges are being requested for Access Tokens. The scopes associated with Access Tokens determine what resources will be available when they are used to access OAuth 2.0 protected endpoints. For OpenID Connect, scopes can be used to request that specific sets of information be made available as Claim Values.","title":"OpenID scopes"},{"location":"admin/admin-ui/auth-server-menu/#spontaneous-scopes","text":"Spontaneous scopes are scopes with random part in it which are not known in advance. For e.g. transaction:4685456787, pis-552fds where 4685456787 or 552fds are generated part of the scope. Spontaneous scopes are disabled by default and can be enabled per client. The admins cannot create a spontaneous scope. Creation only happens when an authorized client presents a spontaneous scope at the token endpoint. There are the following client properties available during dynamic registration of the client related to spontaneous scopes: allowSpontaneousScopes OPTIONAL, boolean, false by default. Whether spontaneous scopes are allowed for the given client. spontaneousScopes OPTIONAL, array of strings. Regular expressions which should match to scope. If matched scope is allowed. Example: [\"^transaction:.+$\"]. It matches transaction:245 but not transaction:.","title":"Spontaneous scopes"},{"location":"admin/admin-ui/auth-server-menu/#uma-scopes","text":"UMA scope can either be created by the user or auto-created by the authentication server. UMA scope cannot be modified using Gluu Flex Admin UI. If the logged-in user creates UMA scope then the creator type will be USER and the creator Id will be logged-in user's INUM. If auth server has auto-created a UMA scope then it will have the creator type as AUTO and no creator Id.","title":"UMA scopes"},{"location":"admin/admin-ui/auth-server-menu/#dynamic-scopes","text":"The dynamic scope custom script allows to generate a list of claims (and their values) on the fly, depending on circumstances like the id of the client requesting it, logged user's session parameters, values of other user's attributes, results of some calculations implementing specific business logic and/or requests to remote APIs or databases. Claims are then returned the usual way in response to a call to the user info endpoint. In order to configure a dynamic scope the following steps are required: The script of type DYNAMIC_SCOPE must be configured and enabled. Create scope of scope type Dynamic and select Dynamic scope script and claims inputs.","title":"Dynamic Scopes"},{"location":"admin/admin-ui/auth-server-menu/#authn","text":"Authentication Context Class Reference (ACR) enables applications to request and verify the level of authentication assurance or the context of the authentication process used for user authentication. This page allows the administrator to view all enabled ACRs and select the default ACR which refers to the predefined or default authentication assurance when no specific ACR value is requested or specified.","title":"Authn"},{"location":"admin/admin-ui/auth-server-menu/#agama","text":"This menu addresses deployment of Agama project packages (file with .gama extension). To make sure that package is untempered, the file containing sha256 checksum also need to be uploaded on UI. The project name, description, version, deployment start/end date-time and deployment error (if any) can be seen on details popup of the record. User can export sample and current configuration or import configuration.","title":"Agama"},{"location":"admin/admin-ui/configuration/","tags":["administration","admin-ui","configuration"],"text":"Configuration # This document outlines the configuration process for Gluu Flex Admin UI, with a focus on essential components stored in the Auth Server's persistence layer. These components include role-permission mapping, OIDC client details for accessing the Auth Server, OIDC client details for accessing the Token Server, OIDC client details for accessing the License APIs, and license metadata. Configuration Components # Role-Permission Mapping # Role-permission mapping defines which administrative roles are granted specific permissions within the Gluu Flex Admin UI. This mapping ensures that administrators can only access and modify functionalities relevant to their roles. The mapping is stored in json format with following attributes. Roles Attribute Name Description roles Array of all roles role Role name description Role description deletable If set to true then entire role-permission mapping with respect to the role can be deleted. Default value: false Permissions Attribute Name Description permissions Array of all available permissions permission Permission name description Permission description defaultPermissionInToken If set to true , it indicates that permission will need authentication and valid role during /token request to include in token Mapping Attribute Name Description rolePermissionMapping List of all role-permission mapping role Role name permission Array of all permission mapped to the role Sample role-permission mapping stored in persistence { \"roles\": [ { \"role\": \"sample-role\", \"description\": \"role description\", \"deletable\": false } ], \"permissions\": [ { \"permission\": \"sample-permission1\", \"description\": \"permission1 description\", \"defaultPermissionInToken\": false }, { \"permission\": \"sample-permission2\", \"description\": \"permission2 description\", \"defaultPermissionInToken\": true } ], \"rolePermissionMapping\": [ { \"role\": \"sample-role\", \"permissions\": [ \"sample-permission1\", \"sample-permission2\" ] } ] } OIDC Client Details for Auth Server # To establish secure communication with the Auth Server, Gluu Flex Admin UI requires the OIDC client details, including client ID and client secret. These details are used for authentication and authorization purposes. The information is stored in json format with following attributes. Attribute Name Description auiWebClient Object with Web OIDC client details opHost Auth Server hostname clientId Client Id of OIDC client used to access Auth server clientSecret Client Secret of OIDC client used to access Auth server scopes Scopes required for Admin UI authentication acrValues ACR required for Admin UI authentication redirectUri Redirect UI which is Admin UI home page postLogoutUri Url to be redirected after Admin UI logout frontchannelLogoutUri Front channel Logout Uri additionalParameters The custom parameters allow you to pass additional information to the authorization server during Admin UI authentication. Format: [{\"key\": \"custom-param-key\", \"value\": \"custom-param-value\"}, ...] OIDC Client Details for Backend API Server # Similarly, Gluu Flex Admin UI needs OIDC client details to interact with the Janssen Server via. Jans Config API protected APIs. The Backend API client enables the UI to request and manage access tokens required to access Jans Config API protected resources. The information is stored in json format with following attributes. Attribute Name Description auiBackendApiClient Object with Backend API client details opHost Token Server hostname clientId Client Id of OIDC client used to access Token server clientSecret Client Secret of OIDC client used to access Token server tokenEndpoint Token endpoint of token server Configuration Properties for User-Interface # Attribute Name Description uiConfig Object with UI configuration attributes sessionTimeoutInMins The admin UI will auto-logout after a period of inactivity defined in this field. OIDC Client Details for License Server # Access to the License APIs is managed through OIDC client details. These details allows the Gluu Flex Admin UI Backend to generated access token to allow the retrieval of license-related information using license APIs. The information is stored in json format with following attributes. Attribute Name Description opHost Auth Server hostname used to generate token to access License APIs clientId Client Id of OIDC client used to generate token to access License APIs clientSecret Client Secret of OIDC client used to generate token to access License APIs License Metadata # License metadata includes relevant information about the Gluu Flex Admin UI's licensing, such as License Key, Hardware id, License server url, License Auth server url, SSA used to register license auth server client. The information is stored in json format with following attributes. Attribute Name Description licenseConfig Object with License configuration details ssa SSA used to register OIDC client to access license APIs scanLicenseApiHostname SCAN License server hostname licenseHardwareKey Hardware key (org_id) to access license APIs Sample configuration stored in persistence { \"oidcConfig\": { \"auiWebClient\": { \"redirectUri\": \"https://your.host.com/admin\", \"postLogoutUri\": \"https://your.gost.com/admin\", \"frontchannelLogoutUri\": \"https://your.host.com/admin/logout\", \"scopes\": [ \"openid\", \"profile\", \"user_name\", \"email\" ], \"acrValues\": [ \"basic\" ], \"opHost\": \"https://your.host.com\", \"clientId\": \"2001.aaf0b8eb-a82e-4798-b1a0-e007803a6568\", \"clientSecret\": \"GGO4t1uixrTpl4Rizt3zag==\". \"additionalParameters\": [] }, \"auiBackendApiClient\": { \"tokenEndpoint\": \"https://your.host.com/jans-auth/restv1/token\", \"scopes\": [ \"openid\", \"profile\", \"user_name\", \"email\" ], \"opHost\": \"https://your.host.com\", \"clientId\": \"2001.aaf0b8eb-a82e-4798-b1a0-e007803a6568\", \"clientSecret\": \"GGO4t1uixrTpl4Rizt3zag==\" } }, \"uiConfig\": { \"sessionTimeoutInMins\": 30 }, \"licenseConfig\": { \"ssa\": \"...ssa in jwt format...\", \"scanLicenseApiHostname\": \"https://cloud-dev.gluu.cloud\", \"licenseKey\": \"XXXX-XXXX-XXXX-XXXX\", \"licenseHardwareKey\": \"github:ghUsername\", \"oidcClient\": { \"opHost\": \"https://account-dev.gluu.cloud\", \"clientId\": \"36a43e2b-a77b-4e9c-a966-a9d98af1665c\", \"clientSecret\": \"211188d8-a2d8-4562-ab53-80907c1bb5ba\" } } }","title":"Configuration"},{"location":"admin/admin-ui/configuration/#configuration","text":"This document outlines the configuration process for Gluu Flex Admin UI, with a focus on essential components stored in the Auth Server's persistence layer. These components include role-permission mapping, OIDC client details for accessing the Auth Server, OIDC client details for accessing the Token Server, OIDC client details for accessing the License APIs, and license metadata.","title":"Configuration"},{"location":"admin/admin-ui/configuration/#configuration-components","text":"","title":"Configuration Components"},{"location":"admin/admin-ui/configuration/#role-permission-mapping","text":"Role-permission mapping defines which administrative roles are granted specific permissions within the Gluu Flex Admin UI. This mapping ensures that administrators can only access and modify functionalities relevant to their roles. The mapping is stored in json format with following attributes. Roles Attribute Name Description roles Array of all roles role Role name description Role description deletable If set to true then entire role-permission mapping with respect to the role can be deleted. Default value: false Permissions Attribute Name Description permissions Array of all available permissions permission Permission name description Permission description defaultPermissionInToken If set to true , it indicates that permission will need authentication and valid role during /token request to include in token Mapping Attribute Name Description rolePermissionMapping List of all role-permission mapping role Role name permission Array of all permission mapped to the role Sample role-permission mapping stored in persistence { \"roles\": [ { \"role\": \"sample-role\", \"description\": \"role description\", \"deletable\": false } ], \"permissions\": [ { \"permission\": \"sample-permission1\", \"description\": \"permission1 description\", \"defaultPermissionInToken\": false }, { \"permission\": \"sample-permission2\", \"description\": \"permission2 description\", \"defaultPermissionInToken\": true } ], \"rolePermissionMapping\": [ { \"role\": \"sample-role\", \"permissions\": [ \"sample-permission1\", \"sample-permission2\" ] } ] }","title":"Role-Permission Mapping"},{"location":"admin/admin-ui/configuration/#oidc-client-details-for-auth-server","text":"To establish secure communication with the Auth Server, Gluu Flex Admin UI requires the OIDC client details, including client ID and client secret. These details are used for authentication and authorization purposes. The information is stored in json format with following attributes. Attribute Name Description auiWebClient Object with Web OIDC client details opHost Auth Server hostname clientId Client Id of OIDC client used to access Auth server clientSecret Client Secret of OIDC client used to access Auth server scopes Scopes required for Admin UI authentication acrValues ACR required for Admin UI authentication redirectUri Redirect UI which is Admin UI home page postLogoutUri Url to be redirected after Admin UI logout frontchannelLogoutUri Front channel Logout Uri additionalParameters The custom parameters allow you to pass additional information to the authorization server during Admin UI authentication. Format: [{\"key\": \"custom-param-key\", \"value\": \"custom-param-value\"}, ...]","title":"OIDC Client Details for Auth Server"},{"location":"admin/admin-ui/configuration/#oidc-client-details-for-backend-api-server","text":"Similarly, Gluu Flex Admin UI needs OIDC client details to interact with the Janssen Server via. Jans Config API protected APIs. The Backend API client enables the UI to request and manage access tokens required to access Jans Config API protected resources. The information is stored in json format with following attributes. Attribute Name Description auiBackendApiClient Object with Backend API client details opHost Token Server hostname clientId Client Id of OIDC client used to access Token server clientSecret Client Secret of OIDC client used to access Token server tokenEndpoint Token endpoint of token server","title":"OIDC Client Details for Backend API Server"},{"location":"admin/admin-ui/configuration/#configuration-properties-for-user-interface","text":"Attribute Name Description uiConfig Object with UI configuration attributes sessionTimeoutInMins The admin UI will auto-logout after a period of inactivity defined in this field.","title":"Configuration Properties for User-Interface"},{"location":"admin/admin-ui/configuration/#oidc-client-details-for-license-server","text":"Access to the License APIs is managed through OIDC client details. These details allows the Gluu Flex Admin UI Backend to generated access token to allow the retrieval of license-related information using license APIs. The information is stored in json format with following attributes. Attribute Name Description opHost Auth Server hostname used to generate token to access License APIs clientId Client Id of OIDC client used to generate token to access License APIs clientSecret Client Secret of OIDC client used to generate token to access License APIs","title":"OIDC Client Details for License Server"},{"location":"admin/admin-ui/configuration/#license-metadata","text":"License metadata includes relevant information about the Gluu Flex Admin UI's licensing, such as License Key, Hardware id, License server url, License Auth server url, SSA used to register license auth server client. The information is stored in json format with following attributes. Attribute Name Description licenseConfig Object with License configuration details ssa SSA used to register OIDC client to access license APIs scanLicenseApiHostname SCAN License server hostname licenseHardwareKey Hardware key (org_id) to access license APIs Sample configuration stored in persistence { \"oidcConfig\": { \"auiWebClient\": { \"redirectUri\": \"https://your.host.com/admin\", \"postLogoutUri\": \"https://your.gost.com/admin\", \"frontchannelLogoutUri\": \"https://your.host.com/admin/logout\", \"scopes\": [ \"openid\", \"profile\", \"user_name\", \"email\" ], \"acrValues\": [ \"basic\" ], \"opHost\": \"https://your.host.com\", \"clientId\": \"2001.aaf0b8eb-a82e-4798-b1a0-e007803a6568\", \"clientSecret\": \"GGO4t1uixrTpl4Rizt3zag==\". \"additionalParameters\": [] }, \"auiBackendApiClient\": { \"tokenEndpoint\": \"https://your.host.com/jans-auth/restv1/token\", \"scopes\": [ \"openid\", \"profile\", \"user_name\", \"email\" ], \"opHost\": \"https://your.host.com\", \"clientId\": \"2001.aaf0b8eb-a82e-4798-b1a0-e007803a6568\", \"clientSecret\": \"GGO4t1uixrTpl4Rizt3zag==\" } }, \"uiConfig\": { \"sessionTimeoutInMins\": 30 }, \"licenseConfig\": { \"ssa\": \"...ssa in jwt format...\", \"scanLicenseApiHostname\": \"https://cloud-dev.gluu.cloud\", \"licenseKey\": \"XXXX-XXXX-XXXX-XXXX\", \"licenseHardwareKey\": \"github:ghUsername\", \"oidcClient\": { \"opHost\": \"https://account-dev.gluu.cloud\", \"clientId\": \"36a43e2b-a77b-4e9c-a966-a9d98af1665c\", \"clientSecret\": \"211188d8-a2d8-4562-ab53-80907c1bb5ba\" } } }","title":"License Metadata"},{"location":"admin/admin-ui/dashboard/","tags":["administration","admin-ui","dashboard"],"text":"Dashboard # After successful authentication, the administrator is taken to the dashboard. The dashboard brings an organized presentation of crucial details at one place adding to the convenience of users in tracking and analysis of auth server and other details. Dashboard fields descriptions # OIDC Clients Count: The count of OIDC clients created on auth server. Active Users Count: The count of active users on auth server. Token Issued Count: This figure is the sum of the access-tokens with grant-type client credentials and authorization code and id-token. OAuth server status: The health status of the auth server. For e.g. Running or Down . Database status: The health status of the persistence (e.g. PostgreSQL, MySQL, Google Spanner etc). License Details # Admin UI uses LicenseSpring platform for customer license management. Product Name: The name of the product created on the LicenseSpring platform. The license issued for Admin UI activation is created under this product. Check LicenseSpring docs for more details. License Type: The type of license issued. For e.g. Perpetual, Time Limited, Subscription and Consumption. Customer Email: To issue a license, we need to enter customer details like first name, last name, company, email and phone number in the LicenseSpring platform. This field displays the email of the customer of the license. Company Name: The company name of the registered product. License Status: The status of the license (e.g. active or inactive). Access Token Graph # The dashboard has a bar graph showing month-wise access-token with grant-type client credentials , authorization code and id_token generated from auth server. Localization and Theme selection # Admin UI supports localization. The default language is English. The other supported languages are French and Portuguese. A new preferred language can be selected from the top right corner of the dashboard which will convert the labels and tooltip to the selected language. The administrator can also select from four website themes in Admin UI.","title":"Home"},{"location":"admin/admin-ui/dashboard/#dashboard","text":"After successful authentication, the administrator is taken to the dashboard. The dashboard brings an organized presentation of crucial details at one place adding to the convenience of users in tracking and analysis of auth server and other details.","title":"Dashboard"},{"location":"admin/admin-ui/dashboard/#dashboard-fields-descriptions","text":"OIDC Clients Count: The count of OIDC clients created on auth server. Active Users Count: The count of active users on auth server. Token Issued Count: This figure is the sum of the access-tokens with grant-type client credentials and authorization code and id-token. OAuth server status: The health status of the auth server. For e.g. Running or Down . Database status: The health status of the persistence (e.g. PostgreSQL, MySQL, Google Spanner etc).","title":"Dashboard fields descriptions"},{"location":"admin/admin-ui/dashboard/#license-details","text":"Admin UI uses LicenseSpring platform for customer license management. Product Name: The name of the product created on the LicenseSpring platform. The license issued for Admin UI activation is created under this product. Check LicenseSpring docs for more details. License Type: The type of license issued. For e.g. Perpetual, Time Limited, Subscription and Consumption. Customer Email: To issue a license, we need to enter customer details like first name, last name, company, email and phone number in the LicenseSpring platform. This field displays the email of the customer of the license. Company Name: The company name of the registered product. License Status: The status of the license (e.g. active or inactive).","title":"License Details"},{"location":"admin/admin-ui/dashboard/#access-token-graph","text":"The dashboard has a bar graph showing month-wise access-token with grant-type client credentials , authorization code and id_token generated from auth server.","title":"Access Token Graph"},{"location":"admin/admin-ui/dashboard/#localization-and-theme-selection","text":"Admin UI supports localization. The default language is English. The other supported languages are French and Portuguese. A new preferred language can be selected from the top right corner of the dashboard which will convert the labels and tooltip to the selected language. The administrator can also select from four website themes in Admin UI.","title":"Localization and Theme selection"},{"location":"admin/admin-ui/faq/","text":"Frequently Asked Questions (FAQ) # Why is the Gluu Flex Admin UI displaying the following error messages after the Flex VM installation? # The requested page not found # Error Code: 404 The requested page was not found on this server. If a user encounters the above error when visiting the Admin UI URL, it indicates that the Admin UI is not properly installed. Please verify whether the Admin UI build is located at /var/www/html/admin . If the build is not present at this location, Janssen displays this error. Admin UI backend is down # Error Code: 503 Gluu Flex Admin UI is not getting any response from the backend (Jans Config Api). Gluu Flex Admin UI facilitates interaction with the Jans Auth Server through a REST API layer, Jans Config API . This error prompts administrators to perform a series of troubleshooting steps. Verify the status of the Jans Config API service by using the command systemctl status jans-config-api.service . In the majority of cases, this error is displayed when the Jans Config API is not running. It is essential to verify the server's network connectivity, including firewall rules, ports, and routing, to ensure that there are no network-related impediments preventing communication with the Jans Config API. Jans Config API runs at port 8074 for Janssen vm installation. Check the Jans Config API logs at /opt/jans/jetty/jans-config-api/logs/configapi.log for any potential errors. Review the Admin UI logs at /opt/jans/jetty/jans-config-api/logs/adminui.log to check for any potential errors. Confirm the existence of the /opt/jans/jetty/jans-config-api/custom/libs/gluu-flex-admin-ui-plugin.jar file. This file serves as the backend jar for the Admin UI and is used as a Jans Config API extension. It is also recommended to check the browser's console log and network tab for any failing requests, as this can provide additional information to diagnose and troubleshoot issues. Internal server error in generating Jans Config Api token # Error Code: 500 Error in generating token to access Jans Config Api endpoints. This error is displayed when there is an internal server error in generating an access token for the Jans Config API. The Jans Config API endpoints are protected and require a token with the appropriate scopes for access. Inspect the Gluu Flex Admin UI log at /opt/jans/jetty/jans-config-api/logs/adminui.log for any errors related to token requests. Examine the Janssen Auth server log at /opt/jans/jetty/jans-auth/logs/jans-auth.log while it is in debug/trace mode to identify any errors that may occur during token generation. Why is the Gluu Flex Admin UI is displaying following page to upload SSA? # During installation, it is necessary to provide a Software Statement Assertion (SSA), which the Admin UI utilizes to register an OIDC client for accessing license APIs. To obtain a new SSA or renew an existing one, please follow the steps outlined in the provided guide from the Agama Lab web interface. If the SSA used during the installation has expired or become invalidated, you will need to upload a fresh SSA to regain access to the Admin UI. Why is the Gluu Flex Admin UI is displaying following message on screen to generate trial license? # Payment Required. This message indicates that in order to enjoy long-term access to the Gluu Flex Admin UI, you will need to subscribe for a Admin UI license on the Agama Lab website. License validity period has expired. This message is displayed when a user attempts to generate a trial license (from the Admin UI) after the previously generated trial license has expired. Please note that the Admin UI 30-day trial license can only be generated once per Agama Lab user.","title":"FAQ & Troubleshooting"},{"location":"admin/admin-ui/faq/#frequently-asked-questions-faq","text":"","title":"Frequently Asked Questions (FAQ)"},{"location":"admin/admin-ui/faq/#why-is-the-gluu-flex-admin-ui-displaying-the-following-error-messages-after-the-flex-vm-installation","text":"","title":"Why is the Gluu Flex Admin UI displaying the following error messages after the Flex VM installation?"},{"location":"admin/admin-ui/faq/#the-requested-page-not-found","text":"Error Code: 404 The requested page was not found on this server. If a user encounters the above error when visiting the Admin UI URL, it indicates that the Admin UI is not properly installed. Please verify whether the Admin UI build is located at /var/www/html/admin . If the build is not present at this location, Janssen displays this error.","title":"The requested page not found"},{"location":"admin/admin-ui/faq/#admin-ui-backend-is-down","text":"Error Code: 503 Gluu Flex Admin UI is not getting any response from the backend (Jans Config Api). Gluu Flex Admin UI facilitates interaction with the Jans Auth Server through a REST API layer, Jans Config API . This error prompts administrators to perform a series of troubleshooting steps. Verify the status of the Jans Config API service by using the command systemctl status jans-config-api.service . In the majority of cases, this error is displayed when the Jans Config API is not running. It is essential to verify the server's network connectivity, including firewall rules, ports, and routing, to ensure that there are no network-related impediments preventing communication with the Jans Config API. Jans Config API runs at port 8074 for Janssen vm installation. Check the Jans Config API logs at /opt/jans/jetty/jans-config-api/logs/configapi.log for any potential errors. Review the Admin UI logs at /opt/jans/jetty/jans-config-api/logs/adminui.log to check for any potential errors. Confirm the existence of the /opt/jans/jetty/jans-config-api/custom/libs/gluu-flex-admin-ui-plugin.jar file. This file serves as the backend jar for the Admin UI and is used as a Jans Config API extension. It is also recommended to check the browser's console log and network tab for any failing requests, as this can provide additional information to diagnose and troubleshoot issues.","title":"Admin UI backend is down"},{"location":"admin/admin-ui/faq/#internal-server-error-in-generating-jans-config-api-token","text":"Error Code: 500 Error in generating token to access Jans Config Api endpoints. This error is displayed when there is an internal server error in generating an access token for the Jans Config API. The Jans Config API endpoints are protected and require a token with the appropriate scopes for access. Inspect the Gluu Flex Admin UI log at /opt/jans/jetty/jans-config-api/logs/adminui.log for any errors related to token requests. Examine the Janssen Auth server log at /opt/jans/jetty/jans-auth/logs/jans-auth.log while it is in debug/trace mode to identify any errors that may occur during token generation.","title":"Internal server error in generating Jans Config Api token"},{"location":"admin/admin-ui/faq/#why-is-the-gluu-flex-admin-ui-is-displaying-following-page-to-upload-ssa","text":"During installation, it is necessary to provide a Software Statement Assertion (SSA), which the Admin UI utilizes to register an OIDC client for accessing license APIs. To obtain a new SSA or renew an existing one, please follow the steps outlined in the provided guide from the Agama Lab web interface. If the SSA used during the installation has expired or become invalidated, you will need to upload a fresh SSA to regain access to the Admin UI.","title":"Why is the Gluu Flex Admin UI is displaying following page to upload SSA?"},{"location":"admin/admin-ui/faq/#why-is-the-gluu-flex-admin-ui-is-displaying-following-message-on-screen-to-generate-trial-license","text":"Payment Required. This message indicates that in order to enjoy long-term access to the Gluu Flex Admin UI, you will need to subscribe for a Admin UI license on the Agama Lab website. License validity period has expired. This message is displayed when a user attempts to generate a trial license (from the Admin UI) after the previously generated trial license has expired. Please note that the Admin UI 30-day trial license can only be generated once per Agama Lab user.","title":"Why is the Gluu Flex Admin UI is displaying following message on screen to generate trial license?"},{"location":"admin/admin-ui/fido-menu/","tags":["administration","admin-ui","fido2"],"text":"FIDO Configuration # FIDO 2.0 (FIDO2) is an open authentication standard that enables people to leverage common devices to authenticate to online services in both mobile and desktop environments. FIDO2 comprises the W3C\u2019s Web Authentication specification (WebAuthn) and FIDO\u2019s corresponding Client-to-Authenticator Protocol (CTAP). WebAuthn defines a standard web API that can be built into browsers and related web platform infrastructure to enable online services to use FIDO Authentication. CTAP enables external devices such as mobile handsets or FIDO Security Keys to work with WebAuthn and serve as authenticators to desktop applications and web services. Gluu Flex Admin UI allows configuring parameters of Janssen's FIDO2 server. Check following documnetation for details of FIDO2 configuration parameters.","title":"FIDO"},{"location":"admin/admin-ui/fido-menu/#fido-configuration","text":"FIDO 2.0 (FIDO2) is an open authentication standard that enables people to leverage common devices to authenticate to online services in both mobile and desktop environments. FIDO2 comprises the W3C\u2019s Web Authentication specification (WebAuthn) and FIDO\u2019s corresponding Client-to-Authenticator Protocol (CTAP). WebAuthn defines a standard web API that can be built into browsers and related web platform infrastructure to enable online services to use FIDO Authentication. CTAP enables external devices such as mobile handsets or FIDO Security Keys to work with WebAuthn and serve as authenticators to desktop applications and web services. Gluu Flex Admin UI allows configuring parameters of Janssen's FIDO2 server. Check following documnetation for details of FIDO2 configuration parameters.","title":"FIDO Configuration"},{"location":"admin/admin-ui/introduction/","tags":["administration","admin-ui","installation","license"],"text":"Gluu Flex Admin UI # Gluu Flex Admin UI is a web interface to simplify the management and configuration of your Janssen Authentication Server. One of the key services offered by Gluu Flex is the ability to view and edit configuration properties, interception scripts, clients, users, metrics, and more, all in one place. This user-friendly interface facilitates interaction with the Jans Auth Server through a REST API layer known as the Jans Config API. The above diagram explains interaction between various depending components. Admin UI Frontend # This user facing GUI has been developed using React.js and Redux is used for state management. The Admin UI utilizes an OpenAPI JavaScript client for Jans Config API, facilitating API calls to Jans Config API endpoints. The GUI utilizes popular libraries such as Material-UI , Axios, Formik , etc. Webpack is responsible for compiling and bundling the application, optimizing its performance, and generating the necessary production files. The Admin UI bundle is hosted on an Apache HTTP server , which is included as a component with the Janssen server installation. This setup ensures that the GUI is readily accessible and efficiently served to users. Admin UI Backend # The GUI utilizes a dedicated Java backend to handle specific tasks, such as reading the Admin UI configuration from persistence, managing Admin UI roles and permission mapping in configuration, performing audit logging, and making calls to license APIs on SCAN. The Jans Config API follows a flexible plugin architecture, allowing the addition of new APIs through extensions known as plugins, without the need to modify the core application. The Admin UI Backend has been incorporated into the Jans Config API as a plugin to address Admin UI-specific tasks. Installation # Gluu Flex can be installed using VM installer or using Rancher on Cloud Native. During installation, we need to provide a Software Statement Assertion (SSA) which is used by Admin UI to register an OIDC client to access license APIs. Check the following guide for the steps to issue SSA from the Agama Lab web interface. Gluu Flex License # After installation, the Admin UI can be accessed at https://hostname/admin (the hostname is provided during setup). Access to this web interface is granted only after subscribing to the Admin UI license from Agama Lab. There is a provision to generate a 30-day free trial license of Gluu Flex which will help users to enter and understand this web interface. After license activation, the user can log into Gluu Flex Admin UI using the default username ( admin ) and the password (the admin password provided during installation). Flex services dependencies # Gluu Flex Admin UI depends on following Flex services: Janssen Config API service (jans-config-api.service) The Apache HTTP Server (apache2.service)","title":"Introduction"},{"location":"admin/admin-ui/introduction/#gluu-flex-admin-ui","text":"Gluu Flex Admin UI is a web interface to simplify the management and configuration of your Janssen Authentication Server. One of the key services offered by Gluu Flex is the ability to view and edit configuration properties, interception scripts, clients, users, metrics, and more, all in one place. This user-friendly interface facilitates interaction with the Jans Auth Server through a REST API layer known as the Jans Config API. The above diagram explains interaction between various depending components.","title":"Gluu Flex Admin UI"},{"location":"admin/admin-ui/introduction/#admin-ui-frontend","text":"This user facing GUI has been developed using React.js and Redux is used for state management. The Admin UI utilizes an OpenAPI JavaScript client for Jans Config API, facilitating API calls to Jans Config API endpoints. The GUI utilizes popular libraries such as Material-UI , Axios, Formik , etc. Webpack is responsible for compiling and bundling the application, optimizing its performance, and generating the necessary production files. The Admin UI bundle is hosted on an Apache HTTP server , which is included as a component with the Janssen server installation. This setup ensures that the GUI is readily accessible and efficiently served to users.","title":"Admin UI Frontend"},{"location":"admin/admin-ui/introduction/#admin-ui-backend","text":"The GUI utilizes a dedicated Java backend to handle specific tasks, such as reading the Admin UI configuration from persistence, managing Admin UI roles and permission mapping in configuration, performing audit logging, and making calls to license APIs on SCAN. The Jans Config API follows a flexible plugin architecture, allowing the addition of new APIs through extensions known as plugins, without the need to modify the core application. The Admin UI Backend has been incorporated into the Jans Config API as a plugin to address Admin UI-specific tasks.","title":"Admin UI Backend"},{"location":"admin/admin-ui/introduction/#installation","text":"Gluu Flex can be installed using VM installer or using Rancher on Cloud Native. During installation, we need to provide a Software Statement Assertion (SSA) which is used by Admin UI to register an OIDC client to access license APIs. Check the following guide for the steps to issue SSA from the Agama Lab web interface.","title":"Installation"},{"location":"admin/admin-ui/introduction/#gluu-flex-license","text":"After installation, the Admin UI can be accessed at https://hostname/admin (the hostname is provided during setup). Access to this web interface is granted only after subscribing to the Admin UI license from Agama Lab. There is a provision to generate a 30-day free trial license of Gluu Flex which will help users to enter and understand this web interface. After license activation, the user can log into Gluu Flex Admin UI using the default username ( admin ) and the password (the admin password provided during installation).","title":"Gluu Flex License"},{"location":"admin/admin-ui/introduction/#flex-services-dependencies","text":"Gluu Flex Admin UI depends on following Flex services: Janssen Config API service (jans-config-api.service) The Apache HTTP Server (apache2.service)","title":"Flex services dependencies"},{"location":"admin/admin-ui/left-nav-menu/","tags":["administration","admin-ui","left navigation menu"],"text":"Left Navigation Menu # In the realm of web design and user experience, the left navigation menu holds a prominent position. It serves as a vital element in organizing and navigating the content within web applications. In Gluu Flex Admin UI the left navigation menu establishes a clear information hierarchy to access the core features. Gluu Flex Admin UI has the following main menus on the left navigation: Home Admin Auth server Schema Services SMTP Users Sign out","title":"Left Navigation Menu"},{"location":"admin/admin-ui/left-nav-menu/#left-navigation-menu","text":"In the realm of web design and user experience, the left navigation menu holds a prominent position. It serves as a vital element in organizing and navigating the content within web applications. In Gluu Flex Admin UI the left navigation menu establishes a clear information hierarchy to access the core features. Gluu Flex Admin UI has the following main menus on the left navigation: Home Admin Auth server Schema Services SMTP Users Sign out","title":"Left Navigation Menu"},{"location":"admin/admin-ui/logs/","tags":["administration","admin-ui","installation","logs"],"text":"Logs # Log files are essential components of a web application's infrastructure as they provide valuable insights into its functioning, performance, and potential issues. Log files play a critical role in maintaining, troubleshooting, and monitoring the Gluu Flex Admin UI application. Understanding the different log types, their locations, and the process of accessing and analyzing them will empower administrators to efficiently manage the application's health and quickly address any issues that may arise. Log File Types # The Gluu Flex Admin UI generates two types of log files: adminui.log : This is the backend log file that captures various activities, errors, and events related to the Gluu Flex Admin UI's operation. It provides insights into the application's behavior and potential issues. adminuiAudit.log : This audit log file records user interactions, actions, and events related to administrative activities. It's particularly useful for tracking changes made to the system and ensuring accountability. Configuration of Log Locations # The log locations for Gluu Flex Admin UI can be configured by modifying the log4j2-adminui.xml file located at: /opt/jans/jetty/jans-config-api/custom/config/log4j2-adminui.xml Within this configuration file, you can adjust various settings such as log levels, appenders, and formats. Default Log Location # The default log location for the Admin UI backend is: /var/log/adminui It is also recommended to check the browser's console log and network tab for any failing requests, as this can provide additional information to diagnose and troubleshoot issues.","title":"Logs"},{"location":"admin/admin-ui/logs/#logs","text":"Log files are essential components of a web application's infrastructure as they provide valuable insights into its functioning, performance, and potential issues. Log files play a critical role in maintaining, troubleshooting, and monitoring the Gluu Flex Admin UI application. Understanding the different log types, their locations, and the process of accessing and analyzing them will empower administrators to efficiently manage the application's health and quickly address any issues that may arise.","title":"Logs"},{"location":"admin/admin-ui/logs/#log-file-types","text":"The Gluu Flex Admin UI generates two types of log files: adminui.log : This is the backend log file that captures various activities, errors, and events related to the Gluu Flex Admin UI's operation. It provides insights into the application's behavior and potential issues. adminuiAudit.log : This audit log file records user interactions, actions, and events related to administrative activities. It's particularly useful for tracking changes made to the system and ensuring accountability.","title":"Log File Types"},{"location":"admin/admin-ui/logs/#configuration-of-log-locations","text":"The log locations for Gluu Flex Admin UI can be configured by modifying the log4j2-adminui.xml file located at: /opt/jans/jetty/jans-config-api/custom/config/log4j2-adminui.xml Within this configuration file, you can adjust various settings such as log levels, appenders, and formats.","title":"Configuration of Log Locations"},{"location":"admin/admin-ui/logs/#default-log-location","text":"The default log location for the Admin UI backend is: /var/log/adminui It is also recommended to check the browser's console log and network tab for any failing requests, as this can provide additional information to diagnose and troubleshoot issues.","title":"Default Log Location"},{"location":"admin/admin-ui/properties/","text":"Where is this content? # The Gluu Flex documentation is a work in progress, and this document is currently a draft. Keep an eye on this page for updates.","title":"Properties"},{"location":"admin/admin-ui/properties/#where-is-this-content","text":"The Gluu Flex documentation is a work in progress, and this document is currently a draft. Keep an eye on this page for updates.","title":"Where is this content?"},{"location":"admin/admin-ui/schema-menu/","tags":["administration","admin-ui","schema","person","attributes"],"text":"Schema # Attributes are individual pieces of user data, like uid or email, that are required by applications in order to identify a user and grant access to protected resources. The Person attributes that are available in your Janssen server can be found by navigating Schema > Person . The following fields are supported in the Person (attribute) creation form: Name: This field defines the name of the Person attribute. The name must be unique in the Janssen Server persistence tree. Display Name: The display name can be anything that is human-readable. Description: The description of the attribute. Status: Used to mark the attribute as Active so that it can be used in your federation service or choose Inactive to create the attribute that can be activated at a later date. Data Type: Select what type of attribute is being added in this field. Edit Type: This field controls who can edit this attribute. If user is selected, this will enable each user to edit this attribute in their Janssen server user profile. View Type: This field controls which type of user is allowed to view the corresponding attribute on the web user interface. oxAuth claim name: If this attribute will be used as a 'claim' in your OpenID Connect service, add the name of the claim here. Generally, the name of the attribute == name of the claim . Multivalued?: If the attribute contains more than one value, set this field to True. Hide On Discovery?: Boolean value indicating if the attribute should be shown on the discovery page. Include In SCIM Extension?: Boolean value indicating if the attribute is a SCIM custom attribute. Enable custom validation for this attribute?: If you plan to set minimum and maximum lengths or a regex pattern, as described below, you will need to enable custom validation for this attribute. Otherwise, you can leave this disabled. Regular expression: You can set a regex pattern to enforce the proper formatting of an attribute. For example, you could set a regex expression for an email attribute like this: ^[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,6}$. This would make sure that a value is added for the attribute only if it follows standard email formatting. Minimum length: This is the minimum length of a value associated with this attribute. Maximum length: This is the maximum length of a value associated with this attribute. Saml1 URI: This field can contain a SAML v1 supported nameformat for the new attribute. If this field is left blank the Janssen Server will automatically populate a value. Saml2 URI: This field can contain a SAML v2 supported nameformat for the new attribute. If this field is left blank the Janssen Server will automatically populate a value.","title":"Schema"},{"location":"admin/admin-ui/schema-menu/#schema","text":"Attributes are individual pieces of user data, like uid or email, that are required by applications in order to identify a user and grant access to protected resources. The Person attributes that are available in your Janssen server can be found by navigating Schema > Person . The following fields are supported in the Person (attribute) creation form: Name: This field defines the name of the Person attribute. The name must be unique in the Janssen Server persistence tree. Display Name: The display name can be anything that is human-readable. Description: The description of the attribute. Status: Used to mark the attribute as Active so that it can be used in your federation service or choose Inactive to create the attribute that can be activated at a later date. Data Type: Select what type of attribute is being added in this field. Edit Type: This field controls who can edit this attribute. If user is selected, this will enable each user to edit this attribute in their Janssen server user profile. View Type: This field controls which type of user is allowed to view the corresponding attribute on the web user interface. oxAuth claim name: If this attribute will be used as a 'claim' in your OpenID Connect service, add the name of the claim here. Generally, the name of the attribute == name of the claim . Multivalued?: If the attribute contains more than one value, set this field to True. Hide On Discovery?: Boolean value indicating if the attribute should be shown on the discovery page. Include In SCIM Extension?: Boolean value indicating if the attribute is a SCIM custom attribute. Enable custom validation for this attribute?: If you plan to set minimum and maximum lengths or a regex pattern, as described below, you will need to enable custom validation for this attribute. Otherwise, you can leave this disabled. Regular expression: You can set a regex pattern to enforce the proper formatting of an attribute. For example, you could set a regex expression for an email attribute like this: ^[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,6}$. This would make sure that a value is added for the attribute only if it follows standard email formatting. Minimum length: This is the minimum length of a value associated with this attribute. Maximum length: This is the maximum length of a value associated with this attribute. Saml1 URI: This field can contain a SAML v1 supported nameformat for the new attribute. If this field is left blank the Janssen Server will automatically populate a value. Saml2 URI: This field can contain a SAML v2 supported nameformat for the new attribute. If this field is left blank the Janssen Server will automatically populate a value.","title":"Schema"},{"location":"admin/admin-ui/services-menu/","tags":["administration","admin-ui","services","cache-configuration"],"text":"Services # This menu allows user to configure Cache Provider and LDAP schemas which can be used by the auth server. Cache Provider Configuration # The following cache providers are supported in Janssen's auth server: In Memory : recommended for small deployments only Memcached : recommended for single cache server deployment Redis : recommended for cluster deployments Native Persistence : recommended avoiding additional components' installation. All cache entries are saved in persistence layers. Cache Provider Properties # The following tables include the name and description of each Cache Provider's properties. Cache Configuration # Name Description Cache Provider Type The cache provider type Memcached Configuration # Name Description Server Details Server details separated by spaces (e.g. `server1:8080 server2:8081) Max Operation Queue Length Maximum number of operations that can be queued Buffer Size Buffer size in bytes Default Put Expiration Expiration timeout value in seconds Connection Factory Type Connection factory type In-Memory Configuration # Name Description Default Put Expiration Default put expiration timeout value in seconds Redis Configuration # Name Description Redis Provider Type Type of connection: standalone, clustered, sharded, sentinel Server Details Server details separated by commas (e.g. 'server1:8080,server2:8081') Use SSL Enable SSL communication between Gluu Server and Redis cache Password Redis password Sentinel Master Group Name Sentinel Master Group Name (required if SENTINEL type of connection is selected) SSL Trust Store File Path Directory Path to Trust Store Default Put Expiration Default expiration time for the object put into cache in seconds Max Retry Attempts Max retry attepts in case of failure So Timeout With this option set to a non-zero timeout, a read() call on the InputStream associated with this Socket will block for only this amount of time. If the timeout expires, a java.net.SocketTimeoutException is raised, though the Socket is still valid. The option must be enabled prior to entering the blocking operation to have effect. The timeout must be > 0. A timeout of zero is interpreted as an infinite timeout. Max Idle Connections The cap on the number of \\\"idle\\\" instances in the pool. If maxIdle is set too low on heavily loaded systems it is possible you will see objects being destroyed and almost immediately new objects being created. This is a result of the active threads momentarily returning objects faster than they are requesting them, causing the number of idle objects to rise above maxIdle. The best value for maxIdle for heavily loaded system will vary but the default is a good starting point. Max Total Connections The number of maximum connection instances in the pool Connection Timeout Connection time out Native Persistence Configuration # Name Description Default Put Expiration Default expiration time for the object put into cache in seconds Default Cleanup Batch Size Default cleanup batch page size Delete Expired OnGetRequest whether to delete on GET request","title":"Services"},{"location":"admin/admin-ui/services-menu/#services","text":"This menu allows user to configure Cache Provider and LDAP schemas which can be used by the auth server.","title":"Services"},{"location":"admin/admin-ui/services-menu/#cache-provider-configuration","text":"The following cache providers are supported in Janssen's auth server: In Memory : recommended for small deployments only Memcached : recommended for single cache server deployment Redis : recommended for cluster deployments Native Persistence : recommended avoiding additional components' installation. All cache entries are saved in persistence layers.","title":"Cache Provider Configuration"},{"location":"admin/admin-ui/services-menu/#cache-provider-properties","text":"The following tables include the name and description of each Cache Provider's properties.","title":"Cache Provider Properties"},{"location":"admin/admin-ui/services-menu/#cache-configuration","text":"Name Description Cache Provider Type The cache provider type","title":"Cache Configuration"},{"location":"admin/admin-ui/services-menu/#memcached-configuration","text":"Name Description Server Details Server details separated by spaces (e.g. `server1:8080 server2:8081) Max Operation Queue Length Maximum number of operations that can be queued Buffer Size Buffer size in bytes Default Put Expiration Expiration timeout value in seconds Connection Factory Type Connection factory type","title":"Memcached Configuration"},{"location":"admin/admin-ui/services-menu/#in-memory-configuration","text":"Name Description Default Put Expiration Default put expiration timeout value in seconds","title":"In-Memory Configuration"},{"location":"admin/admin-ui/services-menu/#redis-configuration","text":"Name Description Redis Provider Type Type of connection: standalone, clustered, sharded, sentinel Server Details Server details separated by commas (e.g. 'server1:8080,server2:8081') Use SSL Enable SSL communication between Gluu Server and Redis cache Password Redis password Sentinel Master Group Name Sentinel Master Group Name (required if SENTINEL type of connection is selected) SSL Trust Store File Path Directory Path to Trust Store Default Put Expiration Default expiration time for the object put into cache in seconds Max Retry Attempts Max retry attepts in case of failure So Timeout With this option set to a non-zero timeout, a read() call on the InputStream associated with this Socket will block for only this amount of time. If the timeout expires, a java.net.SocketTimeoutException is raised, though the Socket is still valid. The option must be enabled prior to entering the blocking operation to have effect. The timeout must be > 0. A timeout of zero is interpreted as an infinite timeout. Max Idle Connections The cap on the number of \\\"idle\\\" instances in the pool. If maxIdle is set too low on heavily loaded systems it is possible you will see objects being destroyed and almost immediately new objects being created. This is a result of the active threads momentarily returning objects faster than they are requesting them, causing the number of idle objects to rise above maxIdle. The best value for maxIdle for heavily loaded system will vary but the default is a good starting point. Max Total Connections The number of maximum connection instances in the pool Connection Timeout Connection time out","title":"Redis Configuration"},{"location":"admin/admin-ui/services-menu/#native-persistence-configuration","text":"Name Description Default Put Expiration Default expiration time for the object put into cache in seconds Default Cleanup Batch Size Default cleanup batch page size Delete Expired OnGetRequest whether to delete on GET request","title":"Native Persistence Configuration"},{"location":"admin/admin-ui/smtp-menu/","tags":["administration","admin-ui","smtp"],"text":"SMTP Configuration # The description of all the fields in SMTP configuration form: Fields Description SMTP Host Hostname of the SMTP server Connect Protection Protocol to protect connection From Name Name of the sender From Email Address Email Address of the Sender Requires Authentication This checkbox enables sender authentication SMTP User Name Username of the SMTP SMTP User Password Password for the SMTP Requires SSL This checkbox enables the SSL SMTP Port Port number of the SMTP server Keystore","title":"SMTP"},{"location":"admin/admin-ui/smtp-menu/#smtp-configuration","text":"The description of all the fields in SMTP configuration form: Fields Description SMTP Host Hostname of the SMTP server Connect Protection Protocol to protect connection From Name Name of the sender From Email Address Email Address of the Sender Requires Authentication This checkbox enables sender authentication SMTP User Name Username of the SMTP SMTP User Password Password for the SMTP Requires SSL This checkbox enables the SSL SMTP Port Port number of the SMTP server Keystore","title":"SMTP Configuration"},{"location":"admin/admin-ui/userMgmt-menu/","tags":["administration","admin-ui","users"],"text":"Users # This interface allows the administrator to create, edit, delete and search user records in Janssen persistence. The user creation/modification form has First Name, Middle Name, Last Name, Username, Display Name, Email, Status and Password fields populated by default on it. The administrator can select and add more user attributes to the form from the right Available Claims panel. To add a new user claim, please follow this document . Different Admin UI Roles can be assigned to the user in the jansAdminUIRole attribute (to be selected from the Available Claims panel).","title":"Users"},{"location":"admin/admin-ui/userMgmt-menu/#users","text":"This interface allows the administrator to create, edit, delete and search user records in Janssen persistence. The user creation/modification form has First Name, Middle Name, Last Name, Username, Display Name, Email, Status and Password fields populated by default on it. The administrator can select and add more user attributes to the form from the right Available Claims panel. To add a new user claim, please follow this document . Different Admin UI Roles can be assigned to the user in the jansAdminUIRole attribute (to be selected from the Available Claims panel).","title":"Users"},{"location":"admin/admin-ui/webhooks/","tags":["administration","admin-ui","webhooks"],"text":"Webhooks # Gluu Flex Admin UI serves as a powerful web interface designed to streamline the management and configuration of the Janssen Authentication Server. To further extend its capabilities, Gluu Flex Admin UI integrates the use of webhooks, enabling the execution of custom business logic during the creation, update, and deletion of information on the Janssen Authentication Server. The seamless integration of webhooks into this interface enhances its functionality, offering a dynamic and extensible solution. Webhooks are a mechanism for automating workflows by allowing external systems to be notified of specific events. In the context of Gluu Flex Admin UI, webhooks can be mapped to various Admin UI features to execute custom business logic when events associated with those features occur. Administrators can map one or more webhooks to specific feature events using the user interface. Webhook management on the UI # The webhook create/update form consists for following fields. Field Description Required Webhook Id The unique identifier of webhook Yes. Generated by Admin UI Webhook Name The name give to webhook Yes URL The webhook url Yes HTTP Method The type HTTP request (e.g. GET, POST, PUT, PATCH, DELETE ) Yes Description Webhook description No Webhook Headers The HTTP request headers No Request Body The HTTP request body Mandatory for POST, PUT, PATCH requests Enabled Toggle switch to enable/disable webhook Yes Admin UI Features The Admin UI features which can be mapped to the webhook No Once a webhook is created it can be searched, edited or deleted. Shortcodes # When working with webhooks, shortcodes play a crucial role in dynamically injecting data into URLs and request bodies. They allow for flexible and customizable communication between different systems. Shortcode is denoted by curly braces ${} . Using shortcodes in webhook url: Shortcodes can be used in path parameters or query parameters of webhook url. https://example.com/webhook/ ${ inum } /update https://example.com/webhook?action = ${ action } & user_id = ${ userId } Using shortcodes in webhook request-body: Webhook request bodies can utilize placeholders to dynamically populate data sent to the recipient system. { \"username\" : \" ${ username } \" , \"email\" : \" ${ email } \" , \"password\" : \" ${ password } \" } Triggering webhooks # The webhooks can be mapped with one or more Admin UI feature(s) using the webhook create/update form . The following Admin UI features can be mapped to the webhooks. Feature Name Action Permission Custom Script Add/Edit https://jans.io/oauth/config/scripts.write Custom Script Delete https://jans.io/oauth/config/scripts.delete FIDO Configuration Edit https://jans.io/oauth/jans-auth-server/config/properties.write Jans Link Edit https://jans.io/oauth/config/jans-link.write OIDC Clients Add/Edit https://jans.io/oauth/config/openid/clients.write OIDC Clients Delete https://jans.io/oauth/config/openid/clients.delete Scopes Add/Edit https://jans.io/oauth/config/scopes.write Scopes Delete https://jans.io/oauth/config/scopes.delete Schema:Person Add/Edit https://jans.io/oauth/config/attributes.write Schema:Person Delete https://jans.io/oauth/config/attributes.delete SCIM Configuration Edit https://jans.io/scim/config.write SMTP Configuration Edit https://jans.io/oauth/config/smtp.write Users Add/Edit https://jans.io/oauth/config/user.write Users Delete https://jans.io/oauth/config/user.delete When the feature action is performed (e.g. submitting the \"create new user\" form), the Admin UI displays the consent dialog with a list of webhooks that will be triggered upon the successful execution of the event. If the user clicks on the Accept button, all the enabled webhooks will be triggered during the event execution. The Admin UI is unable to proceed with event execution if any webhook fails during the process.","title":"Webhooks"},{"location":"admin/admin-ui/webhooks/#webhooks","text":"Gluu Flex Admin UI serves as a powerful web interface designed to streamline the management and configuration of the Janssen Authentication Server. To further extend its capabilities, Gluu Flex Admin UI integrates the use of webhooks, enabling the execution of custom business logic during the creation, update, and deletion of information on the Janssen Authentication Server. The seamless integration of webhooks into this interface enhances its functionality, offering a dynamic and extensible solution. Webhooks are a mechanism for automating workflows by allowing external systems to be notified of specific events. In the context of Gluu Flex Admin UI, webhooks can be mapped to various Admin UI features to execute custom business logic when events associated with those features occur. Administrators can map one or more webhooks to specific feature events using the user interface.","title":"Webhooks"},{"location":"admin/admin-ui/webhooks/#webhook-management-on-the-ui","text":"The webhook create/update form consists for following fields. Field Description Required Webhook Id The unique identifier of webhook Yes. Generated by Admin UI Webhook Name The name give to webhook Yes URL The webhook url Yes HTTP Method The type HTTP request (e.g. GET, POST, PUT, PATCH, DELETE ) Yes Description Webhook description No Webhook Headers The HTTP request headers No Request Body The HTTP request body Mandatory for POST, PUT, PATCH requests Enabled Toggle switch to enable/disable webhook Yes Admin UI Features The Admin UI features which can be mapped to the webhook No Once a webhook is created it can be searched, edited or deleted.","title":"Webhook management on the UI"},{"location":"admin/admin-ui/webhooks/#shortcodes","text":"When working with webhooks, shortcodes play a crucial role in dynamically injecting data into URLs and request bodies. They allow for flexible and customizable communication between different systems. Shortcode is denoted by curly braces ${} . Using shortcodes in webhook url: Shortcodes can be used in path parameters or query parameters of webhook url. https://example.com/webhook/ ${ inum } /update https://example.com/webhook?action = ${ action } & user_id = ${ userId } Using shortcodes in webhook request-body: Webhook request bodies can utilize placeholders to dynamically populate data sent to the recipient system. { \"username\" : \" ${ username } \" , \"email\" : \" ${ email } \" , \"password\" : \" ${ password } \" }","title":"Shortcodes"},{"location":"admin/admin-ui/webhooks/#triggering-webhooks","text":"The webhooks can be mapped with one or more Admin UI feature(s) using the webhook create/update form . The following Admin UI features can be mapped to the webhooks. Feature Name Action Permission Custom Script Add/Edit https://jans.io/oauth/config/scripts.write Custom Script Delete https://jans.io/oauth/config/scripts.delete FIDO Configuration Edit https://jans.io/oauth/jans-auth-server/config/properties.write Jans Link Edit https://jans.io/oauth/config/jans-link.write OIDC Clients Add/Edit https://jans.io/oauth/config/openid/clients.write OIDC Clients Delete https://jans.io/oauth/config/openid/clients.delete Scopes Add/Edit https://jans.io/oauth/config/scopes.write Scopes Delete https://jans.io/oauth/config/scopes.delete Schema:Person Add/Edit https://jans.io/oauth/config/attributes.write Schema:Person Delete https://jans.io/oauth/config/attributes.delete SCIM Configuration Edit https://jans.io/scim/config.write SMTP Configuration Edit https://jans.io/oauth/config/smtp.write Users Add/Edit https://jans.io/oauth/config/user.write Users Delete https://jans.io/oauth/config/user.delete When the feature action is performed (e.g. submitting the \"create new user\" form), the Admin UI displays the consent dialog with a list of webhooks that will be triggered upon the successful execution of the event. If the user clicks on the Accept button, all the enabled webhooks will be triggered during the event execution. The Admin UI is unable to proceed with event execution if any webhook fails during the process.","title":"Triggering webhooks"},{"location":"admin/kubernetes-ops/","tags":["administration","kubernetes","operations"],"text":"Overview # This Operation guide helps you learn about the common operations for Gluu Flex on Kubernetes. Note Since Flex = Janssen + Admin-UI. The Kubernetes Operations in Gluu Flex are identitical to Janssen . You will mostly only need to change the helm chart reference from janssen/janssen to gluu-flex/gluu , along with the helm release name and namespace. Here's an example how would the upgrade of Flex looks like. Common Operations # Upgrade Admin-UI Private Scaling Backup and Restore Certificate Management Customization Start Order Logs External Secrets and Configmaps Health Check TUI K8s Custom Attributes Jans SAML/Keycloak Memory Dump","title":"Overview"},{"location":"admin/kubernetes-ops/#overview","text":"This Operation guide helps you learn about the common operations for Gluu Flex on Kubernetes. Note Since Flex = Janssen + Admin-UI. The Kubernetes Operations in Gluu Flex are identitical to Janssen . You will mostly only need to change the helm chart reference from janssen/janssen to gluu-flex/gluu , along with the helm release name and namespace. Here's an example how would the upgrade of Flex looks like.","title":"Overview"},{"location":"admin/kubernetes-ops/#common-operations","text":"Upgrade Admin-UI Private Scaling Backup and Restore Certificate Management Customization Start Order Logs External Secrets and Configmaps Health Check TUI K8s Custom Attributes Jans SAML/Keycloak Memory Dump","title":"Common Operations"},{"location":"admin/kubernetes-ops/admin-ui-private/","tags":["administration","kubernetes","operations","private","internal","admin-ui"],"text":"Overview # This document demonstrates a method to override the URLs in the admin-ui used to connect to the backend services, such as the config API. This way the calls are made privately without hitting the FQDN through the internet. Configuration # We will install nginx in ingress-nginx namespace using the following command: helm install ingress-nginx ingress-nginx/ingress-nginx -n ingress-nginx and thus, the svc is accessible at ingress-nginx-controller.ingress-nginx.svc.cluster.local Modify values.yaml : admin-ui : usrEnvs : normal : CN_CONFIG_API_BASE_URL : https://ingress.local:8443 CN_AUTH_BASE_URL : https://ingress.local:8443 CN_TOKEN_SERVER_BASE_URL : https://ingress-nginx-controller.ingress-nginx.svc.cluster.local config-api : usrEnvs : normal : CN_TOKEN_SERVER_BASE_URL : https://ingress-nginx-controller.ingress-nginx.svc.cluster.local nginx-ingress : ingress : hosts : - demoexample.gluu.org # adjust Gluu FQDN used as needed - ingress-nginx-controller.ingress-nginx.svc.cluster.local - ingress.local Deploy the flex helm chart using the updated values.yaml To allow the browser to access internal service, add an entry inside /etc/hosts file: 127.0.0.1 ingress.local ingress-nginx-controller.ingress-nginx.svc.cluster.local By default, the ingress-nginx-controller deployment uses fake certificate generated by k8s. Add a new certificate (self-signed certificate and key are sufficient) as the default certificate into the ingress controller. Generate SSL cert and key using your preferred tool. Make sure to add domain ingress-nginx-controller.ingress-nginx.svc.cluster.local and ingress.local in SAN section. Example: openssl req -x509 -newkey rsa:4096 -sha256 -days 365 -nodes -keyout ingress.local.key -out ingress.local.crt -subj \"/CN=ingress.local\" -addext \"subjectAltName=DNS:ingress.local,DNS:ingress-nginx-controller.ingress-nginx.svc.cluster.local\" Create secrets to store the certificate and key, for example: kubectl -n create secret tls internal-tls-certificate --cert /path/to/cert --key /path/to/key Modify the ingress-nginx-controller deployment: apiVersion : apps/v1 kind : Deployment metadata : name : ingress-nginx-controller namespace : ingress-nginx spec : template : spec : containers : - args : # some arguments are omitted # add a new argument to load self-signed cert - --default-ssl-certificate=/internal-tls-certificate Rollout restart the ingress-nginx-controller deployment. Expose the service IP (port 443) to host (port 8443): kubectl -n ingress-nginx port-forward svc/ingress-nginx-controller 8443:443 & OPTIONAL : if the K8s cluster is deployed at a remote VM, make SSH tunneling before accessing the admin-ui web: ssh -N -L 8443:localhost:8443 @ & Hit https://ingress.local:8443 and allow the browser to skip certificate validation. Visit https:///admin","title":"Admin-UI Private"},{"location":"admin/kubernetes-ops/admin-ui-private/#overview","text":"This document demonstrates a method to override the URLs in the admin-ui used to connect to the backend services, such as the config API. This way the calls are made privately without hitting the FQDN through the internet.","title":"Overview"},{"location":"admin/kubernetes-ops/admin-ui-private/#configuration","text":"We will install nginx in ingress-nginx namespace using the following command: helm install ingress-nginx ingress-nginx/ingress-nginx -n ingress-nginx and thus, the svc is accessible at ingress-nginx-controller.ingress-nginx.svc.cluster.local Modify values.yaml : admin-ui : usrEnvs : normal : CN_CONFIG_API_BASE_URL : https://ingress.local:8443 CN_AUTH_BASE_URL : https://ingress.local:8443 CN_TOKEN_SERVER_BASE_URL : https://ingress-nginx-controller.ingress-nginx.svc.cluster.local config-api : usrEnvs : normal : CN_TOKEN_SERVER_BASE_URL : https://ingress-nginx-controller.ingress-nginx.svc.cluster.local nginx-ingress : ingress : hosts : - demoexample.gluu.org # adjust Gluu FQDN used as needed - ingress-nginx-controller.ingress-nginx.svc.cluster.local - ingress.local Deploy the flex helm chart using the updated values.yaml To allow the browser to access internal service, add an entry inside /etc/hosts file: 127.0.0.1 ingress.local ingress-nginx-controller.ingress-nginx.svc.cluster.local By default, the ingress-nginx-controller deployment uses fake certificate generated by k8s. Add a new certificate (self-signed certificate and key are sufficient) as the default certificate into the ingress controller. Generate SSL cert and key using your preferred tool. Make sure to add domain ingress-nginx-controller.ingress-nginx.svc.cluster.local and ingress.local in SAN section. Example: openssl req -x509 -newkey rsa:4096 -sha256 -days 365 -nodes -keyout ingress.local.key -out ingress.local.crt -subj \"/CN=ingress.local\" -addext \"subjectAltName=DNS:ingress.local,DNS:ingress-nginx-controller.ingress-nginx.svc.cluster.local\" Create secrets to store the certificate and key, for example: kubectl -n create secret tls internal-tls-certificate --cert /path/to/cert --key /path/to/key Modify the ingress-nginx-controller deployment: apiVersion : apps/v1 kind : Deployment metadata : name : ingress-nginx-controller namespace : ingress-nginx spec : template : spec : containers : - args : # some arguments are omitted # add a new argument to load self-signed cert - --default-ssl-certificate=/internal-tls-certificate Rollout restart the ingress-nginx-controller deployment. Expose the service IP (port 443) to host (port 8443): kubectl -n ingress-nginx port-forward svc/ingress-nginx-controller 8443:443 & OPTIONAL : if the K8s cluster is deployed at a remote VM, make SSH tunneling before accessing the admin-ui web: ssh -N -L 8443:localhost:8443 @ & Hit https://ingress.local:8443 and allow the browser to skip certificate validation. Visit https:///admin","title":"Configuration"},{"location":"admin/kubernetes-ops/upgrade/","tags":["administration","kubernetes","operations","helm","upgrade"],"text":"This guide shows how to upgrade a Gluu Flex helm deployment. helm ls -n Keep note of the helm release version Add your changes to override.yaml Apply your upgrade: helm upgrade gluu-flex/gluu -n -f override.yaml --version=5.1.6.nightly","title":"Upgrade"},{"location":"admin/recipes/","tags":["administration","recipes"],"text":"Overview # Please use the left navigation menu to browse the content of this section while we are still working on developing content for Overview page.","title":"Overview"},{"location":"admin/recipes/#overview","text":"Please use the left navigation menu to browse the content of this section while we are still working on developing content for Overview page.","title":"Overview"},{"location":"admin/recipes/getting-started-rancher/","text":"Overview # Gluu Flex (\u201cFlex\u201d) is a cloud-native digital identity platform that enables organizations to authenticate and authorize people and software through the use of open standards like OpenID Connect, OAuth, and FIDO. It is a downstream commercial distribution of the Linux Foundation Janssen Project software, plus a web administration tool(Gluu Admin-UI). SUSE Rancher\u2019s helm-based deployment approach simplifies the deployment and configuration of Flex, enabling organizations to take advantage of Flex\u2019s modular design to improve their security posture while simultaneously enabling just-in-time auto-scaling. The key services of Flex include: (REQUIRED) Jans Auth Server : This component is the OAuth Authorization Server, the OpenID Connect Provider, and the UMA Authorization Server for person and software authentication. This service must be Internet-facing. (REQUIRED) Jans Config API : The API to configure the auth-server and other components is consolidated in this component. This service should not be Internet-facing. Gluu Admin UI : Web admin tool for ad-hoc configuration. Jans Fido : This component provides the server-side endpoints to enroll and validate devices that use FIDO. It provides both FIDO U2F (register, authenticate) and FIDO 2 (attestation, assertion) endpoints. This service must be Internet-facing. Jans SCIM : System for Cross-domain Identity Management ( SCIM ) is JSON/REST API to manage user data. Use it to add, edit and update user information. This service should not be Internet-facing. Jans Casa : A self-service web portal for end-users to manage authentication and authorization preferences for their account in the Gluu Flex server. Typically, it enables people to manage their MFA credentials, like FIDO tokens and OTP authenticators. It's also extensible if your organization has any other self-service requirements. Building Blocks # Scope # In this Quickstart Guide, we will: Deploy Flex and add some users. Enable two-factor authentication. Protect content on an Apache web server with OpenID Connect. Audience # This document is intended for DevOps engineers, site reliability engineers (SREs), platform engineers, software engineers, and developers who are responsible for managing and running stateful workloads in Kubernetes clusters. Technical overview # In addition to the core services listed in the Introduction above, the SUSE Rancher deployment includes the following components: PostgreSQL/MySQL : SQL database dialect used to store configuration, people clients, sessions and other data needed for Gluu Flex operation. Cert Manager : Used for managing X.509 certificates and crypto keys lifecycle in Janssen Server. Key Rotation : A cronjob that implements Cert Manager to rotate the auth keys Configuration job : loads (generate/restore) and dumps (backup) the configuration and secrets. Persistence job : This job loads initial data for the backend used (SQL or Couchbase). ConfigMaps : Stores configuration needed for Flex environment setup. Secrets : Contains sensitive or confidential data such as a password, a token, or a key. Config and Secret keys # The Configuration job creates a set of configurations and secrets used by all services in the Flex setup. To check the values of the configuration keys(configmaps) in the installation: kubectl get cm cn -o json -n To check the values of the secret keys in installation: kubectl get secret cn -o json -n Gluu Config Keys # Key Example Values admin_email team@gluu.org admin_inum d3afef58-c026-4514-9d4c-e0a3efb4c29d admin_ui_client_id 1901.a6575c1e-4688-4c11-8c95-d9e570b13ee8 auth_enc_keys RSA1_5 RSA-OAEP auth_key_rotated_at 1653517558 auth_legacyIdTokenClaims false auth_openidScopeBackwardCompatibility false auth_openid_jks_fn /etc/certs/auth-keys.jks auth_openid_jwks_fn /etc/certs/auth-keys.json casa_client_id 0008-db36db1f-025e-4164-aeed-f82df064eee8 auth_sig_keys RS256 RS384 RS512 ES256 ES384 ES512 PS384 PS512 city Austin country_code US default_openid_jks_dn_name CN=Janssen Auth CA Certificate fido2ConfigFolder /etc/jans/conf/fido2 hostname demoexample.gluu.org jca_client_id 1801.4df6c3ba-ebf6-4836-8fb5-6da927586f61 optional_scopes [\\\"casa\\\", \\\"sql\\\", \\\"fido2\\\", \\\"scim\\\"] orgName Gluu tui_client_id 2000.9313cd4b-147c-4a67-96be-8a69ddbaf7e9 scim_client_id 1201.1cbcc731-3fca-4668-a480-1b5f5a7d6a53 state TX token_server_admin_ui_client_id 1901.57a858dc-69f3-4967-befe-e089fe376638 Gluu Secret Keys # Key Example Values admin_ui_client_encoded_pw QlBMMTZUZWVYeWczVlpNUk1XN0pzdzrg admin_ui_client_pw WnJYZEcyVlNBWG9d auth_jks_base64 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx auth_openid_jks_pass TWZoR3Rlb0NnUHEP auth_openid_key_base64 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx casa_client_encoded_pw b3NabG9oVGNncFVVWFpxNEJMU3V0dzrg casa_client_pw M1g0Z1dEbGNPQ19d encoded_admin_password e3NzaGF9eGpOaDRyblU3dzJZbmpPclovMUlheTdkR0RrOTdLe encoded_salt Um9NSEJnOU9IbTRvRkJHVVZETVZIeXEP jca_client_encoded_pw Um9NSEJnOU9IbTRvRkJHVVZETVZIeX58 jca_client_pw Um9NSEJnOU9IbTRvR otp_configuration xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx pairwiseCalculationKey ZHd2VW01Y3VOUW6638ZHd2VW pairwiseCalculationSalt ZHd2VW01Y3VOUW6638ZHd2VW0 plugins_admin_ui_properties xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx tui_client_encoded_pw ZHd2VW01Y3VOUW66388PS512 tui_client_pw AusZHd2VW01Y3VOUW6638 scim_client_encoded_pw UZHd2VW01Y3VOUW6638ZHd2VW01Y3VOUW6638 scim_client_pw ZHd2VW01Y3VOUW6638 sql_password ZHd2VW01Y3V638 ssl_ca_cert xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ssl_ca_key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ssl_cert xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ssl_csr xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ssl_key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx super_gluu_creds xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx3 token_server_admin_ui_client_encoded_pw Q1Z1cmtYWUlYSVg4U2tLTldVcnZVTUF token_server_admin_ui_client_pw ZHd2VW01Y3VOUW6638 Prerequisites # SUSE Rancher installed with an accessible UI Kubernetes cluster running on SUSE Rancher with at least 1 worker node Sufficient RBAC permissions to deploy and manage applications in the cluster. LinuxIO kernel modules on the worker nodes Docker running locally (Linux preferred) Essential tools and CLI utilities are installed on your local workstation and are available in your $PATH : curl , kubectl An entry in the /etc/hosts file of your local workstation to resolve the hostname of the Gluu Flex installation. This step is for testing purposes. Installation # Summary of steps : Install Database: Note For the Database test setup to work, a PV provisioner support must be present in the underlying infrastructure. Install PostgreSQL database # Note If you are willing to use MySQL installation, skip this section and head to the Install MySQL section. To install a quick setup with PostgreSQL as the backend, you need to provide the connection parameters of a fresh setup. For a test setup, you can follow the below instructions: Apps --> Charts and search for Postgres . Click on Install on the right side of the window. Create a new namespace called postgres and hit Next . You should be on the Edit YAML page. Modify the below keys as desired. These values will be inputted in the installation of Gluu Flex Key auth.database auth.username auth.password Click Install at the bottom right of the page. Install MySQL database # Note Skip this section if you installed PostgreSQL . This section is only needed if you are willing to use MySQL. To install a quick setup with MySQL as the backend, you need to provide the connection parameters of a fresh setup. For a test setup, you can follow the below instructions: Open a kubectl shell from the top right navigation menu >_ . Run: helm repo add bitnami https://charts.bitnami.com/bitnami helm repo update kubectl create ns gluu #Create gluu namespace Pass in a custom password for the database. Here we used Test1234# . The admin user will be left as root . Notice we are installing in the gluu namespace. Run helm install my-release --set auth.rootPassword=Test1234#,auth.database=jans bitnami/mysql -n gluu Successful Installation # After the installation is successful, you should have a Statefulset active in the rancher UI as shown in the screenshot below. Install Nginx-Ingress , if you are not using Istio ingress helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx helm repo add stable https://charts.helm.sh/stable helm repo update helm install nginx ingress-nginx/ingress-nginx To get the Loadbalancer IP: kubectl get svc nginx-ingress-nginx-controller --output jsonpath='{.status.loadBalancer.ingress[0].ip}' Install Gluu Flex: Head to Apps --> Charts and search for Gluu Click on Install on the right side of the window. Change the namespace from default to gluu , then click on Next . Scroll through the sections to get familiar with the options. For minimal setup follow with the next instructions. Add License SSA . Before initiating the setup, please obtain an SSA for Flex trial, after which you will issued a JWT. Click on the Persistence section. Change SQL database host uri to postgresql.postgres.svc.cluster.local in the case of PostgreSQL or my-release-mysql.gluu.svc.cluster.local in the case of MySQL . Also set SQL database username , SQL password , and SQL database name to the values you used during the database installation. To enable Casa and the Admin UI, navigate to the Optional Services section and check the Enable casa and boolean flag to enable admin UI boxes. You can also enable different services like Client API and Jackrabbit . Click on the section named Ingress and enable all the endpoints. You might add LB IP or address if you don't have FQDN for Gluu . To pass your FQDN or Domain that is intended to serve the Gluu Flex IDP, head to the Configuration section: Add your FQDN and check the box Is the FQDN globally resolvable . Click on the Edit YAML tab and add your FQDN to nginx-ingress.ingress.hosts and nginx-ingress.ingress.tls.hosts . Click on Install on the bottom right of the window. Note You can upgrade your installation after the deployment. To do that, go to the SUSE Rancher Dashboard -> Apps -> Installed Apps -> gluu -> Click on the 3 dots on the right -> Upgrade -> Make your changes -> Click Update. The running deployment and services of different Gluu Flex components like casa , admin-ui , scim , auth-server , etc can be viewed by navigating through the SUSE Rancher. Go to Workloads and see the running pods. Go under Service Discovery and checkout the Ingresses and Services . All deployed components should be in a healthy and running state like in the screenshot shown below. Connecting to the Setup # Note You can skip this section if you have a globally resolvable FQDN . In the event you used microk8s or your fqdn is not registered, the below steps will help with connecting to your setup. To access the setup from a browser or another VM, we need to change the ingress class annotation from kubernetes.io/ingress.class: nginx to kubernetes.io/ingress.class: public e.g., for the specific component you want to access publicly in the browser; Navigate through the SUSE Rancher UI to Service Discovery -> Ingresses Choose the ingress for the targeted component. For example gluu-nginx-ingress-auth-server for auth-server Click on the three dots in the top right corner Click on Edit Yaml On line 8, change the kubernetes.io/ingress.class annotation value from nginx to public Click Save The LoadBalancer IP needs to get mapped inside /etc/hosts with the domain chosen for gluu flex . If the domain you used in the setup is demoexample.gluu.org: 3.65.27.95 demoexample.gluu.org You can do the same edit for every component you want to access publicly from the browser. Testing Configuration endpoints # Try accessing some Gluu Flex endpoints like https://demoexample.gluu.org/.well-known/openid-configuration in the browser and you'll get back a JSON response; Note that you can also access those endpoints via curl command, E.g. curl -k https://demoexample.gluu.org/.well-known/openid-configuration You should get a similar response like the one below; {\"version\":\"1.1\",\"issuer\":\"https://demoexample.gluu.org\",\"attestation\":{\"base_path\":\"https://demoexample.gluu.org/jans-fido2/restv1/attestation\",\"options_enpoint\":\"https://demoexample.gluu.org/jans-fido2/restv1/attestation/options\",\"result_enpoint\":\"https://demoexample.gluu.org/jans-fido2/restv1/attestation/result\"},\"assertion\":{\"base_path\":\"https://demoexample.gluu.org/jans-fido2/restv1/assertion\",\"options_enpoint\":\"https://demoexample.gluu.org/jans-fido2/restv1/assertion/options\",\"result_enpoint\":\"https://demoexample.gluu.org/jans-fido2/restv1/assertion/result\"}} Login and Add a New User # After inputting the license keys, you can then use admin and the password you set to login to the Admin UI and you should see the Admin UI dashboard. You could also add another test user via the admin UI that will be used for testing Casa and 2FA as shown in the screenshot below. Navigate to Users and click on + in the top right corner to add a user. Testing Casa # Jans Casa (\"Casa\") is a self-service web portal for managing account security preferences. The primary use case for Casa is self-service 2FA, but other use cases and functionalities can be supported via Casa plugins. Although you have not enabled two-factor authentication yet, you should still be able to login to Casa as the admin user and the password is the one you set during installation. Point your browser to https://demoexample.gluu.org/jans-casa and you should be welcomed by the Casa login page as shown below. After logging in, you'll be welcomed by the home page as shown below. Enabling Two-Factor Authentication # In this part, we are going to enable two standard authentication mechanisms: OTP and FIDO. This can be done through the admin UI. 2FA can be turned on by clicking the switch in the Second Factor Authentication widget. By default, you will be able to choose from a few 2FA policies: Always (upon every login attempt) If the location (e.g. city) detected in the login attempt is unrecognized If the device used to login is unrecognized To reduce the chance of account lockout, enroll at least two different types of 2FA credentials -- e.g. one security key and one OTP app; or one OTP app and one SMS phone number, etc. This way, regardless of which device you're using to access a protected resource, you will have a usable option for passing strong authentication. To enable 2FA, firstly the OTP and FIDO components have to be enabled in the Casa admin UI then login to Casa as an end user, and register an OTP device (i.e. Google Authenticator) and a FIDO device. Register OTP device To add a new OTP token, navigate to 2FA credentials > OTP Tokens. You can either add a soft OTP token by choosing the Soft token option or a hard token by choosing the Hard Token Option Check the soft OTP token and click ready Before proceeding to the next step, Download Google Authenticator from Google Play or Appstore Then proceed and scan the QR code with your app Enter the 6-digit code that appears in your authenticator app and validate the enrollment. Register Fido device To add a new FIDO 2 credential, navigate to 2FA credentials > Security Keys and built-in Platform Authenticators Insert the fido key and click Ready. Casa will prompt you to press the button on the key. Add a nickname and click Add. Once added, the new device will appear in a list on the same page. Click the pencil to edit the device's nickname Testing Apache OIDC Locally # In this part, we are going to use docker to locally configure an apache web server, and then install the mod_auth_openidc module and configure it accordingly. Using local docker containers, our approach is to first register a client, then spin up two Apache containers, one serving static content (with server-side includes configured so we can display headers and environment information), and one acting as the OpenID Connect authenticating reverse proxy. Register an OpenID Connect client # On the Janssen server, you can register a new client in the Flex Admin UI or the jans-cli. In this section, we are going to show both ways of doing it from the Admin UI and using jans-cli Admin UI # Navigate to Auth server -> Clients and click on + in the top right corner to create a client. Take note of the following keys:values because they configure the right client that we need scopes: email_,openid_,profile responseTypes: code The screenshot below shows an example of the Admin UI section from where a client is created Jans TUI # On the Janssen server, we are going to register a new client using the jans-cli. There are two ways you can register an OIDC client with the Janssen server, Manual Client Registration and Dynamic Client Registration (DCR). Here we will use manual client registration. We will use jans-tui tool provided by the Janssen server. jans-tui has a menu-driven interface that makes it easy to configure the Janssen server. Here we will use the menu-driven approach to register a new client. Download jans-cli-tui from the release assets depending on your OS. For example: wget https://github.com/JanssenProject/jans/releases/download/vreplace-janssen-version/jans-cli-tui-linux-ubuntu-X86-64.pyz Now we have jans-cli-tui-linux-ubuntu-X86-64.pyz downloaded. Now we can grab the FQDN, client-id, client-secret, and connect using the following commands: FQDN= #Add your FQDN here TUI_CLIENT_ID=$(kubectl get cm cn -n --template={{.data.tui_client_id}}) TUI_CLIENT_SECRET=$(kubectl get secret cn -n --template={{.data.tui_client_pw}} | base64 -d) #add -noverify if your FQDN is not registered Get schema file using this command python3 jans-cli-tui-linux-ubuntu-X86-64.pyz --host --client-id --client-secret --no-tui --schema /components/schemas/Client Add values for required params and store this JSON in a text file. Take keynote of the following properties. schema-json-file.json { \"dn\": null, \"inum\": null, \"displayName\": \"\", \"clientSecret\": \"\", \"frontChannelLogoutUri\": null, \"frontChannelLogoutSessionRequired\": null, \"registrationAccessToken\": null, \"clientIdIssuedAt\": null, \"clientSecretExpiresAt\": null, \"redirectUris\": [ \"\" ], \"claimRedirectUris\": null, \"responseTypes\": [ \"code\" ], \"grantTypes\": [ \"authorization_code\" ], \"applicationType\": \"web\", \"contacts\": null, \"idTokenTokenBindingCnf\": null, \"logoUri\": null, \"clientUri\": null, \"policyUri\": null, \"tosUri\": null, \"jwksUri\": null, \"jwks\": null, \"sectorIdentifierUri\": null, \"subjectType\": \"public\", \"idTokenSignedResponseAlg\": null, \"idTokenEncryptedResponseAlg\": null, \"idTokenEncryptedResponseEnc\": null, \"userInfoSignedResponseAlg\": null, \"userInfoEncryptedResponseAlg\": null, \"userInfoEncryptedResponseEnc\": null, \"requestObjectSigningAlg\": null, \"requestObjectEncryptionAlg\": null, \"requestObjectEncryptionEnc\": null, \"tokenEndpointAuthMethod\": \"client_secret_basic\", \"tokenEndpointAuthSigningAlg\": null, \"defaultMaxAge\": null, \"requireAuthTime\": null, \"defaultAcrValues\": null, \"initiateLoginUri\": null, \"postLogoutRedirectUris\": null, \"requestUris\": null, \"scopes\": [ \"email\", \"openid\", \"profile\" ], \"claims\": null, \"trustedClient\": false, \"lastAccessTime\": null, \"lastLogonTime\": null, \"persistClientAuthorizations\": null, \"includeClaimsInIdToken\": false, \"refreshTokenLifetime\": null, \"accessTokenLifetime\": null, \"customAttributes\": null, \"customObjectClasses\": null, \"rptAsJwt\": null, \"accessTokenAsJwt\": null, \"accessTokenSigningAlg\": null, \"disabled\": false, \"authorizedOrigins\": null, \"softwareId\": null, \"softwareVersion\": null, \"softwareStatement\": null, \"attributes\": null, \"backchannelTokenDeliveryMode\": null, \"backchannelClientNotificationEndpoint\": null, \"backchannelAuthenticationRequestSigningAlg\": null, \"backchannelUserCodeParameter\": null, \"expirationDate\": null, \"deletable\": false, \"jansId\": null, \"description\": null } Now you can use that JSON file as input to the command below and register your client python3 jans-cli-tui-linux-ubuntu-X86-64.pyz --host --client-id --client-secret --no-tui --operation-id=post-oauth-openid-client --data /schema-json-file.json After the client is successfully registered, there will be data that describes the newly registered client. Some of these values, like inum and clientSecret , will be required before we configure mod_auth_openidc So keep in mind that we shall get back to this. Create an Application Container # An application docker container will be run locally which will act as the protected resource (PR) / external application. The following files have code for the small application. We shall create a directory locally / on your machine called test and add the required files. Firstly create a project folder named test by running mkdir test && cd test and add the following files with their content; app.conf ServerRoot \"/usr/local/apache2\" Listen 80 LoadModule mpm_event_module modules/mod_mpm_event.so LoadModule authz_core_module modules/mod_authz_core.so LoadModule include_module modules/mod_include.so LoadModule filter_module modules/mod_filter.so LoadModule mime_module modules/mod_mime.so LoadModule log_config_module modules/mod_log_config.so LoadModule setenvif_module modules/mod_setenvif.so LoadModule unixd_module modules/mod_unixd.so LoadModule dir_module modules/mod_dir.so User daemon Group daemon AllowOverride none Require all denied DocumentRoot \"/usr/local/apache2/htdocs\" Options Indexes FollowSymLinks Includes AllowOverride None Require all granted SetEnvIf X-Remote-User \"(.*)\" REMOTE_USER=$0 SetEnvIf X-Remote-User-Name \"(.*)\" REMOTE_USER_NAME=$0 SetEnvIf X-Remote-User-Email \"(.*)\" REMOTE_USER_EMAIL=$0 DirectoryIndex index.html Require all denied ErrorLog /proc/self/fd/2 LogLevel warn LogFormat \"%h %l %u %t \\\"%r\\\" %>s %b \\\"%{Referer}i\\\" \\\"%{User-Agent}i\\\"\" combined LogFormat \"%h %l %u %t \\\"%r\\\" %>s %b\" common CustomLog /proc/self/fd/1 common TypesConfig conf/mime.types AddType application/x-compress .Z AddType application/x-gzip .gz .tgz AddType text/html .shtml AddOutputFilter INCLUDES .shtml user.shtml Hello User

              Hello !

              You authenticated as:

              Your email address is:

              Environment:

              !

              index.html Hello World

              Hello world!

              Dockerfile FROM httpd:2.4.54@sha256:c9eba4494b9d856843b49eb897f9a583a0873b1c14c86d5ab77e5bdedd6ad05d # \"Created\": \"2022-06-08T18:45:46.260791323Z\" , \"Version\":\"2.4.54\" RUN apt-get update \\ && apt-get install -y --no-install-recommends wget ca-certificates libcjose0 libhiredis0.14 apache2-api-20120211 apache2-bin\\ && wget https://github.com/zmartzone/mod_auth_openidc/releases/download/v2.4.11.2/libapache2-mod-auth-openidc_2.4.11.2-1.buster+1_amd64.deb \\ && dpkg -i libapache2-mod-auth-openidc_2.4.11.2-1.buster+1_amd64.deb \\ && ln -s /usr/lib/apache2/modules/mod_auth_openidc.so /usr/local/apache2/modules/mod_auth_openidc.so \\ && rm -rf /var/log/dpkg.log /var/log/alternatives.log /var/log/apt \\ && touch /usr/local/apache2/conf/extra/secret.conf \\ && touch /usr/local/apache2/conf/extra/oidc.conf RUN echo \"\\n\\nLoadModule auth_openidc_module modules/mod_auth_openidc.so\\n\\nInclude conf/extra/secret.conf\\nInclude conf/extra/oidc.conf\\n\" >> /usr/local/apache2/conf/httpd.conf gluu.secret.conf OIDCClientID OIDCCryptoPassphrase OIDCClientSecret OIDCResponseType code OIDCScope \"openid email profile\" OIDCProviderTokenEndpointAuth client_secret_basic OIDCSSLValidateServer Off OIDCRedirectURI http://localhost:8111/oauth2callback OIDCCryptoPassphrase Require valid-user AuthType openid-connect After, run an Apache container which will play the role of an application being protected by the authenticating reverse proxy. docker run -dit -p 8110:80 \\ -v \"$PWD/app.conf\":/usr/local/apache2/conf/httpd.conf \\ -v \"$PWD/index.html\":/usr/local/apache2/htdocs/index.html \\ -v \"$PWD/user.shtml\":/usr/local/apache2/htdocs/user.shtml \\ --name apache-app httpd:2.4 Note that we are using a popular pre-built image useful for acting as a reverse proxy for authentication in front of an application. It contains a stripped-down Apache with minimal modules, and adds the mod_auth_openidc module for performing OpenID Connect authentication. Make a test curl command call to ensure you get back some content as shown in the screenshot below curl http://localhost:8110/user.shtml Create an Authenticating Reverse Proxy Container # We shall use Apache, but this time we use a Docker image that has mod_auth_oidc installed and configured. This proxy will require authentication, handle the authentication flow with redirects, and then forward requests to the application. In order to use this, you will need to have registered a new OpenID Connect client on the Janssen server. We did that in the step 1 above Add the following files to the test folder. oidc.conf # Unset to make sure clients can't control these RequestHeader unset X-Remote-User RequestHeader unset X-Remote-User-Name RequestHeader unset X-Remote-User-Email # If you want to see tons of logs for your experimentation #LogLevel trace8 OIDCClientID OIDCProviderMetadataURL https://idp-proxy.med.stanford.edu/auth/realms/med-all/.well-known/openid-configuration #OIDCProviderMetadataURL https://idp-proxy-stage.med.stanford.edu/auth/realms/choir/.well-known/openid-configuration OIDCRedirectURI http://localhost:8111/oauth2callback OIDCScope \"openid email profile\" OIDCRemoteUserClaim principal OIDCPassClaimsAs environment AuthType openid-connect Require valid-user ProxyPass http://app:80/ ProxyPassReverse http://app:80/ RequestHeader set X-Remote-User %{OIDC_CLAIM_principal}e RequestHeader set X-Remote-User-Name %{OIDC_CLAIM_name}e RequestHeader set X-Remote-User-Email %{OIDC_CLAIM_email}e proxy.conf # This is the main Apache HTTP server configuration file. For documentation, see: # http://httpd.apache.org/docs/2.4/ # http://httpd.apache.org/docs/2.4/mod/directives.html # # This is intended to be a hardened configuration, with minimal security surface area necessary # to run mod_auth_openidc. ServerRoot \"/usr/local/apache2\" Listen 80 LoadModule mpm_event_module modules/mod_mpm_event.so LoadModule authn_file_module modules/mod_authn_file.so LoadModule authn_core_module modules/mod_authn_core.so LoadModule authz_host_module modules/mod_authz_host.so LoadModule authz_groupfile_module modules/mod_authz_groupfile.so LoadModule authz_user_module modules/mod_authz_user.so LoadModule authz_core_module modules/mod_authz_core.so LoadModule access_compat_module modules/mod_access_compat.so LoadModule auth_basic_module modules/mod_auth_basic.so LoadModule reqtimeout_module modules/mod_reqtimeout.so LoadModule filter_module modules/mod_filter.so LoadModule mime_module modules/mod_mime.so LoadModule log_config_module modules/mod_log_config.so LoadModule env_module modules/mod_env.so LoadModule headers_module modules/mod_headers.so LoadModule setenvif_module modules/mod_setenvif.so #LoadModule version_module modules/mod_version.so LoadModule proxy_module modules/mod_proxy.so LoadModule proxy_http_module modules/mod_proxy_http.so LoadModule unixd_module modules/mod_unixd.so #LoadModule status_module modules/mod_status.so #LoadModule autoindex_module modules/mod_autoindex.so LoadModule dir_module modules/mod_dir.so LoadModule alias_module modules/mod_alias.so User daemon Group daemon ServerAdmin you@example.com AllowOverride none Require all denied DocumentRoot \"/usr/local/apache2/htdocs\" Options Indexes FollowSymLinks AllowOverride None Require all granted DirectoryIndex index.html Options None Require all denied Require all denied ErrorLog /proc/self/fd/2 LogLevel warn LogFormat \"%h %l %u %t \\\"%r\\\" %>s %b \\\"%{Referer}i\\\" \\\"%{User-Agent}i\\\"\" combined LogFormat \"%h %l %u %t \\\"%r\\\" %>s %b\" common LogFormat \"%h %l %u %t \\\"%r\\\" %>s %b \\\"%{Referer}i\\\" \\\"%{User-Agent}i\\\" %I %O\" combinedio CustomLog /proc/self/fd/1 common ScriptAlias /cgi-bin/ \"/usr/local/apache2/cgi-bin/\" AllowOverride None Options None Require all granted RequestHeader unset Proxy early TypesConfig conf/mime.types AddType application/x-compress .Z AddType application/x-gzip .gz .tgz Include conf/extra/proxy-html.conf SSLRandomSeed startup builtin SSLRandomSeed connect builtin TraceEnable off ServerTokens Prod ServerSignature Off LoadModule auth_openidc_module modules/mod_auth_openidc.so Include conf/extra/secret.conf Include conf/extra/oidc.conf Edit the file to include the client secret for the client you created during DCR, and add a securely generated pass phrase for the session keys docker build --pull -t apache-oidc -f Dockerfile . docker run -dit -p 8111:80 \\ -v \"$PWD/proxy.conf\":/usr/local/apache2/conf/httpd.conf \\ -v \"$PWD/gluu.secret.conf\":/usr/local/apache2/conf/extra/secret.conf \\ -v \"$PWD/oidc.conf\":/usr/local/apache2/conf/extra/oidc.conf \\ --link apache-app:app \\ --name apache-proxy apache-oidc Now open a fresh web browser with private (incognito) mode, and go to this url http://localhost:8111/user.shtml To check the proxy logs docker logs -f apache-proxy To see the app logs docker logs -f apache-app If you modified the configuration files, just restart the proxy. docker restart apache-proxy","title":"Getting Started with Rancher"},{"location":"admin/recipes/getting-started-rancher/#overview","text":"Gluu Flex (\u201cFlex\u201d) is a cloud-native digital identity platform that enables organizations to authenticate and authorize people and software through the use of open standards like OpenID Connect, OAuth, and FIDO. It is a downstream commercial distribution of the Linux Foundation Janssen Project software, plus a web administration tool(Gluu Admin-UI). SUSE Rancher\u2019s helm-based deployment approach simplifies the deployment and configuration of Flex, enabling organizations to take advantage of Flex\u2019s modular design to improve their security posture while simultaneously enabling just-in-time auto-scaling. The key services of Flex include: (REQUIRED) Jans Auth Server : This component is the OAuth Authorization Server, the OpenID Connect Provider, and the UMA Authorization Server for person and software authentication. This service must be Internet-facing. (REQUIRED) Jans Config API : The API to configure the auth-server and other components is consolidated in this component. This service should not be Internet-facing. Gluu Admin UI : Web admin tool for ad-hoc configuration. Jans Fido : This component provides the server-side endpoints to enroll and validate devices that use FIDO. It provides both FIDO U2F (register, authenticate) and FIDO 2 (attestation, assertion) endpoints. This service must be Internet-facing. Jans SCIM : System for Cross-domain Identity Management ( SCIM ) is JSON/REST API to manage user data. Use it to add, edit and update user information. This service should not be Internet-facing. Jans Casa : A self-service web portal for end-users to manage authentication and authorization preferences for their account in the Gluu Flex server. Typically, it enables people to manage their MFA credentials, like FIDO tokens and OTP authenticators. It's also extensible if your organization has any other self-service requirements.","title":"Overview"},{"location":"admin/recipes/getting-started-rancher/#building-blocks","text":"","title":"Building Blocks"},{"location":"admin/recipes/getting-started-rancher/#scope","text":"In this Quickstart Guide, we will: Deploy Flex and add some users. Enable two-factor authentication. Protect content on an Apache web server with OpenID Connect.","title":"Scope"},{"location":"admin/recipes/getting-started-rancher/#audience","text":"This document is intended for DevOps engineers, site reliability engineers (SREs), platform engineers, software engineers, and developers who are responsible for managing and running stateful workloads in Kubernetes clusters.","title":"Audience"},{"location":"admin/recipes/getting-started-rancher/#technical-overview","text":"In addition to the core services listed in the Introduction above, the SUSE Rancher deployment includes the following components: PostgreSQL/MySQL : SQL database dialect used to store configuration, people clients, sessions and other data needed for Gluu Flex operation. Cert Manager : Used for managing X.509 certificates and crypto keys lifecycle in Janssen Server. Key Rotation : A cronjob that implements Cert Manager to rotate the auth keys Configuration job : loads (generate/restore) and dumps (backup) the configuration and secrets. Persistence job : This job loads initial data for the backend used (SQL or Couchbase). ConfigMaps : Stores configuration needed for Flex environment setup. Secrets : Contains sensitive or confidential data such as a password, a token, or a key.","title":"Technical overview"},{"location":"admin/recipes/getting-started-rancher/#config-and-secret-keys","text":"The Configuration job creates a set of configurations and secrets used by all services in the Flex setup. To check the values of the configuration keys(configmaps) in the installation: kubectl get cm cn -o json -n To check the values of the secret keys in installation: kubectl get secret cn -o json -n ","title":"Config and Secret keys"},{"location":"admin/recipes/getting-started-rancher/#gluu-config-keys","text":"Key Example Values admin_email team@gluu.org admin_inum d3afef58-c026-4514-9d4c-e0a3efb4c29d admin_ui_client_id 1901.a6575c1e-4688-4c11-8c95-d9e570b13ee8 auth_enc_keys RSA1_5 RSA-OAEP auth_key_rotated_at 1653517558 auth_legacyIdTokenClaims false auth_openidScopeBackwardCompatibility false auth_openid_jks_fn /etc/certs/auth-keys.jks auth_openid_jwks_fn /etc/certs/auth-keys.json casa_client_id 0008-db36db1f-025e-4164-aeed-f82df064eee8 auth_sig_keys RS256 RS384 RS512 ES256 ES384 ES512 PS384 PS512 city Austin country_code US default_openid_jks_dn_name CN=Janssen Auth CA Certificate fido2ConfigFolder /etc/jans/conf/fido2 hostname demoexample.gluu.org jca_client_id 1801.4df6c3ba-ebf6-4836-8fb5-6da927586f61 optional_scopes [\\\"casa\\\", \\\"sql\\\", \\\"fido2\\\", \\\"scim\\\"] orgName Gluu tui_client_id 2000.9313cd4b-147c-4a67-96be-8a69ddbaf7e9 scim_client_id 1201.1cbcc731-3fca-4668-a480-1b5f5a7d6a53 state TX token_server_admin_ui_client_id 1901.57a858dc-69f3-4967-befe-e089fe376638","title":"Gluu Config Keys"},{"location":"admin/recipes/getting-started-rancher/#gluu-secret-keys","text":"Key Example Values admin_ui_client_encoded_pw QlBMMTZUZWVYeWczVlpNUk1XN0pzdzrg admin_ui_client_pw WnJYZEcyVlNBWG9d auth_jks_base64 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx auth_openid_jks_pass TWZoR3Rlb0NnUHEP auth_openid_key_base64 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx casa_client_encoded_pw b3NabG9oVGNncFVVWFpxNEJMU3V0dzrg casa_client_pw M1g0Z1dEbGNPQ19d encoded_admin_password e3NzaGF9eGpOaDRyblU3dzJZbmpPclovMUlheTdkR0RrOTdLe encoded_salt Um9NSEJnOU9IbTRvRkJHVVZETVZIeXEP jca_client_encoded_pw Um9NSEJnOU9IbTRvRkJHVVZETVZIeX58 jca_client_pw Um9NSEJnOU9IbTRvR otp_configuration xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx pairwiseCalculationKey ZHd2VW01Y3VOUW6638ZHd2VW pairwiseCalculationSalt ZHd2VW01Y3VOUW6638ZHd2VW0 plugins_admin_ui_properties xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx tui_client_encoded_pw ZHd2VW01Y3VOUW66388PS512 tui_client_pw AusZHd2VW01Y3VOUW6638 scim_client_encoded_pw UZHd2VW01Y3VOUW6638ZHd2VW01Y3VOUW6638 scim_client_pw ZHd2VW01Y3VOUW6638 sql_password ZHd2VW01Y3V638 ssl_ca_cert xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ssl_ca_key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ssl_cert xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ssl_csr xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ssl_key xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx super_gluu_creds xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx3 token_server_admin_ui_client_encoded_pw Q1Z1cmtYWUlYSVg4U2tLTldVcnZVTUF token_server_admin_ui_client_pw ZHd2VW01Y3VOUW6638","title":"Gluu Secret Keys"},{"location":"admin/recipes/getting-started-rancher/#prerequisites","text":"SUSE Rancher installed with an accessible UI Kubernetes cluster running on SUSE Rancher with at least 1 worker node Sufficient RBAC permissions to deploy and manage applications in the cluster. LinuxIO kernel modules on the worker nodes Docker running locally (Linux preferred) Essential tools and CLI utilities are installed on your local workstation and are available in your $PATH : curl , kubectl An entry in the /etc/hosts file of your local workstation to resolve the hostname of the Gluu Flex installation. This step is for testing purposes.","title":"Prerequisites"},{"location":"admin/recipes/getting-started-rancher/#installation","text":"Summary of steps : Install Database: Note For the Database test setup to work, a PV provisioner support must be present in the underlying infrastructure.","title":"Installation"},{"location":"admin/recipes/getting-started-rancher/#install-postgresql-database","text":"Note If you are willing to use MySQL installation, skip this section and head to the Install MySQL section. To install a quick setup with PostgreSQL as the backend, you need to provide the connection parameters of a fresh setup. For a test setup, you can follow the below instructions: Apps --> Charts and search for Postgres . Click on Install on the right side of the window. Create a new namespace called postgres and hit Next . You should be on the Edit YAML page. Modify the below keys as desired. These values will be inputted in the installation of Gluu Flex Key auth.database auth.username auth.password Click Install at the bottom right of the page.","title":"Install PostgreSQL database"},{"location":"admin/recipes/getting-started-rancher/#install-mysql-database","text":"Note Skip this section if you installed PostgreSQL . This section is only needed if you are willing to use MySQL. To install a quick setup with MySQL as the backend, you need to provide the connection parameters of a fresh setup. For a test setup, you can follow the below instructions: Open a kubectl shell from the top right navigation menu >_ . Run: helm repo add bitnami https://charts.bitnami.com/bitnami helm repo update kubectl create ns gluu #Create gluu namespace Pass in a custom password for the database. Here we used Test1234# . The admin user will be left as root . Notice we are installing in the gluu namespace. Run helm install my-release --set auth.rootPassword=Test1234#,auth.database=jans bitnami/mysql -n gluu","title":"Install MySQL database"},{"location":"admin/recipes/getting-started-rancher/#successful-installation","text":"After the installation is successful, you should have a Statefulset active in the rancher UI as shown in the screenshot below. Install Nginx-Ingress , if you are not using Istio ingress helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx helm repo add stable https://charts.helm.sh/stable helm repo update helm install nginx ingress-nginx/ingress-nginx To get the Loadbalancer IP: kubectl get svc nginx-ingress-nginx-controller --output jsonpath='{.status.loadBalancer.ingress[0].ip}' Install Gluu Flex: Head to Apps --> Charts and search for Gluu Click on Install on the right side of the window. Change the namespace from default to gluu , then click on Next . Scroll through the sections to get familiar with the options. For minimal setup follow with the next instructions. Add License SSA . Before initiating the setup, please obtain an SSA for Flex trial, after which you will issued a JWT. Click on the Persistence section. Change SQL database host uri to postgresql.postgres.svc.cluster.local in the case of PostgreSQL or my-release-mysql.gluu.svc.cluster.local in the case of MySQL . Also set SQL database username , SQL password , and SQL database name to the values you used during the database installation. To enable Casa and the Admin UI, navigate to the Optional Services section and check the Enable casa and boolean flag to enable admin UI boxes. You can also enable different services like Client API and Jackrabbit . Click on the section named Ingress and enable all the endpoints. You might add LB IP or address if you don't have FQDN for Gluu . To pass your FQDN or Domain that is intended to serve the Gluu Flex IDP, head to the Configuration section: Add your FQDN and check the box Is the FQDN globally resolvable . Click on the Edit YAML tab and add your FQDN to nginx-ingress.ingress.hosts and nginx-ingress.ingress.tls.hosts . Click on Install on the bottom right of the window. Note You can upgrade your installation after the deployment. To do that, go to the SUSE Rancher Dashboard -> Apps -> Installed Apps -> gluu -> Click on the 3 dots on the right -> Upgrade -> Make your changes -> Click Update. The running deployment and services of different Gluu Flex components like casa , admin-ui , scim , auth-server , etc can be viewed by navigating through the SUSE Rancher. Go to Workloads and see the running pods. Go under Service Discovery and checkout the Ingresses and Services . All deployed components should be in a healthy and running state like in the screenshot shown below.","title":"Successful Installation"},{"location":"admin/recipes/getting-started-rancher/#connecting-to-the-setup","text":"Note You can skip this section if you have a globally resolvable FQDN . In the event you used microk8s or your fqdn is not registered, the below steps will help with connecting to your setup. To access the setup from a browser or another VM, we need to change the ingress class annotation from kubernetes.io/ingress.class: nginx to kubernetes.io/ingress.class: public e.g., for the specific component you want to access publicly in the browser; Navigate through the SUSE Rancher UI to Service Discovery -> Ingresses Choose the ingress for the targeted component. For example gluu-nginx-ingress-auth-server for auth-server Click on the three dots in the top right corner Click on Edit Yaml On line 8, change the kubernetes.io/ingress.class annotation value from nginx to public Click Save The LoadBalancer IP needs to get mapped inside /etc/hosts with the domain chosen for gluu flex . If the domain you used in the setup is demoexample.gluu.org: 3.65.27.95 demoexample.gluu.org You can do the same edit for every component you want to access publicly from the browser.","title":"Connecting to the Setup"},{"location":"admin/recipes/getting-started-rancher/#testing-configuration-endpoints","text":"Try accessing some Gluu Flex endpoints like https://demoexample.gluu.org/.well-known/openid-configuration in the browser and you'll get back a JSON response; Note that you can also access those endpoints via curl command, E.g. curl -k https://demoexample.gluu.org/.well-known/openid-configuration You should get a similar response like the one below; {\"version\":\"1.1\",\"issuer\":\"https://demoexample.gluu.org\",\"attestation\":{\"base_path\":\"https://demoexample.gluu.org/jans-fido2/restv1/attestation\",\"options_enpoint\":\"https://demoexample.gluu.org/jans-fido2/restv1/attestation/options\",\"result_enpoint\":\"https://demoexample.gluu.org/jans-fido2/restv1/attestation/result\"},\"assertion\":{\"base_path\":\"https://demoexample.gluu.org/jans-fido2/restv1/assertion\",\"options_enpoint\":\"https://demoexample.gluu.org/jans-fido2/restv1/assertion/options\",\"result_enpoint\":\"https://demoexample.gluu.org/jans-fido2/restv1/assertion/result\"}}","title":"Testing Configuration endpoints"},{"location":"admin/recipes/getting-started-rancher/#login-and-add-a-new-user","text":"After inputting the license keys, you can then use admin and the password you set to login to the Admin UI and you should see the Admin UI dashboard. You could also add another test user via the admin UI that will be used for testing Casa and 2FA as shown in the screenshot below. Navigate to Users and click on + in the top right corner to add a user.","title":"Login and Add a New User"},{"location":"admin/recipes/getting-started-rancher/#testing-casa","text":"Jans Casa (\"Casa\") is a self-service web portal for managing account security preferences. The primary use case for Casa is self-service 2FA, but other use cases and functionalities can be supported via Casa plugins. Although you have not enabled two-factor authentication yet, you should still be able to login to Casa as the admin user and the password is the one you set during installation. Point your browser to https://demoexample.gluu.org/jans-casa and you should be welcomed by the Casa login page as shown below. After logging in, you'll be welcomed by the home page as shown below.","title":"Testing Casa"},{"location":"admin/recipes/getting-started-rancher/#enabling-two-factor-authentication","text":"In this part, we are going to enable two standard authentication mechanisms: OTP and FIDO. This can be done through the admin UI. 2FA can be turned on by clicking the switch in the Second Factor Authentication widget. By default, you will be able to choose from a few 2FA policies: Always (upon every login attempt) If the location (e.g. city) detected in the login attempt is unrecognized If the device used to login is unrecognized To reduce the chance of account lockout, enroll at least two different types of 2FA credentials -- e.g. one security key and one OTP app; or one OTP app and one SMS phone number, etc. This way, regardless of which device you're using to access a protected resource, you will have a usable option for passing strong authentication. To enable 2FA, firstly the OTP and FIDO components have to be enabled in the Casa admin UI then login to Casa as an end user, and register an OTP device (i.e. Google Authenticator) and a FIDO device. Register OTP device To add a new OTP token, navigate to 2FA credentials > OTP Tokens. You can either add a soft OTP token by choosing the Soft token option or a hard token by choosing the Hard Token Option Check the soft OTP token and click ready Before proceeding to the next step, Download Google Authenticator from Google Play or Appstore Then proceed and scan the QR code with your app Enter the 6-digit code that appears in your authenticator app and validate the enrollment. Register Fido device To add a new FIDO 2 credential, navigate to 2FA credentials > Security Keys and built-in Platform Authenticators Insert the fido key and click Ready. Casa will prompt you to press the button on the key. Add a nickname and click Add. Once added, the new device will appear in a list on the same page. Click the pencil to edit the device's nickname","title":"Enabling Two-Factor Authentication"},{"location":"admin/recipes/getting-started-rancher/#testing-apache-oidc-locally","text":"In this part, we are going to use docker to locally configure an apache web server, and then install the mod_auth_openidc module and configure it accordingly. Using local docker containers, our approach is to first register a client, then spin up two Apache containers, one serving static content (with server-side includes configured so we can display headers and environment information), and one acting as the OpenID Connect authenticating reverse proxy.","title":"Testing Apache OIDC Locally"},{"location":"admin/recipes/getting-started-rancher/#register-an-openid-connect-client","text":"On the Janssen server, you can register a new client in the Flex Admin UI or the jans-cli. In this section, we are going to show both ways of doing it from the Admin UI and using jans-cli","title":"Register an OpenID Connect client"},{"location":"admin/recipes/getting-started-rancher/#admin-ui","text":"Navigate to Auth server -> Clients and click on + in the top right corner to create a client. Take note of the following keys:values because they configure the right client that we need scopes: email_,openid_,profile responseTypes: code The screenshot below shows an example of the Admin UI section from where a client is created","title":"Admin UI"},{"location":"admin/recipes/getting-started-rancher/#jans-tui","text":"On the Janssen server, we are going to register a new client using the jans-cli. There are two ways you can register an OIDC client with the Janssen server, Manual Client Registration and Dynamic Client Registration (DCR). Here we will use manual client registration. We will use jans-tui tool provided by the Janssen server. jans-tui has a menu-driven interface that makes it easy to configure the Janssen server. Here we will use the menu-driven approach to register a new client. Download jans-cli-tui from the release assets depending on your OS. For example: wget https://github.com/JanssenProject/jans/releases/download/vreplace-janssen-version/jans-cli-tui-linux-ubuntu-X86-64.pyz Now we have jans-cli-tui-linux-ubuntu-X86-64.pyz downloaded. Now we can grab the FQDN, client-id, client-secret, and connect using the following commands: FQDN= #Add your FQDN here TUI_CLIENT_ID=$(kubectl get cm cn -n --template={{.data.tui_client_id}}) TUI_CLIENT_SECRET=$(kubectl get secret cn -n --template={{.data.tui_client_pw}} | base64 -d) #add -noverify if your FQDN is not registered Get schema file using this command python3 jans-cli-tui-linux-ubuntu-X86-64.pyz --host --client-id --client-secret --no-tui --schema /components/schemas/Client Add values for required params and store this JSON in a text file. Take keynote of the following properties. schema-json-file.json { \"dn\": null, \"inum\": null, \"displayName\": \"\", \"clientSecret\": \"\", \"frontChannelLogoutUri\": null, \"frontChannelLogoutSessionRequired\": null, \"registrationAccessToken\": null, \"clientIdIssuedAt\": null, \"clientSecretExpiresAt\": null, \"redirectUris\": [ \"\" ], \"claimRedirectUris\": null, \"responseTypes\": [ \"code\" ], \"grantTypes\": [ \"authorization_code\" ], \"applicationType\": \"web\", \"contacts\": null, \"idTokenTokenBindingCnf\": null, \"logoUri\": null, \"clientUri\": null, \"policyUri\": null, \"tosUri\": null, \"jwksUri\": null, \"jwks\": null, \"sectorIdentifierUri\": null, \"subjectType\": \"public\", \"idTokenSignedResponseAlg\": null, \"idTokenEncryptedResponseAlg\": null, \"idTokenEncryptedResponseEnc\": null, \"userInfoSignedResponseAlg\": null, \"userInfoEncryptedResponseAlg\": null, \"userInfoEncryptedResponseEnc\": null, \"requestObjectSigningAlg\": null, \"requestObjectEncryptionAlg\": null, \"requestObjectEncryptionEnc\": null, \"tokenEndpointAuthMethod\": \"client_secret_basic\", \"tokenEndpointAuthSigningAlg\": null, \"defaultMaxAge\": null, \"requireAuthTime\": null, \"defaultAcrValues\": null, \"initiateLoginUri\": null, \"postLogoutRedirectUris\": null, \"requestUris\": null, \"scopes\": [ \"email\", \"openid\", \"profile\" ], \"claims\": null, \"trustedClient\": false, \"lastAccessTime\": null, \"lastLogonTime\": null, \"persistClientAuthorizations\": null, \"includeClaimsInIdToken\": false, \"refreshTokenLifetime\": null, \"accessTokenLifetime\": null, \"customAttributes\": null, \"customObjectClasses\": null, \"rptAsJwt\": null, \"accessTokenAsJwt\": null, \"accessTokenSigningAlg\": null, \"disabled\": false, \"authorizedOrigins\": null, \"softwareId\": null, \"softwareVersion\": null, \"softwareStatement\": null, \"attributes\": null, \"backchannelTokenDeliveryMode\": null, \"backchannelClientNotificationEndpoint\": null, \"backchannelAuthenticationRequestSigningAlg\": null, \"backchannelUserCodeParameter\": null, \"expirationDate\": null, \"deletable\": false, \"jansId\": null, \"description\": null } Now you can use that JSON file as input to the command below and register your client python3 jans-cli-tui-linux-ubuntu-X86-64.pyz --host --client-id --client-secret --no-tui --operation-id=post-oauth-openid-client --data /schema-json-file.json After the client is successfully registered, there will be data that describes the newly registered client. Some of these values, like inum and clientSecret , will be required before we configure mod_auth_openidc So keep in mind that we shall get back to this.","title":"Jans TUI"},{"location":"admin/recipes/getting-started-rancher/#create-an-application-container","text":"An application docker container will be run locally which will act as the protected resource (PR) / external application. The following files have code for the small application. We shall create a directory locally / on your machine called test and add the required files. Firstly create a project folder named test by running mkdir test && cd test and add the following files with their content; app.conf ServerRoot \"/usr/local/apache2\" Listen 80 LoadModule mpm_event_module modules/mod_mpm_event.so LoadModule authz_core_module modules/mod_authz_core.so LoadModule include_module modules/mod_include.so LoadModule filter_module modules/mod_filter.so LoadModule mime_module modules/mod_mime.so LoadModule log_config_module modules/mod_log_config.so LoadModule setenvif_module modules/mod_setenvif.so LoadModule unixd_module modules/mod_unixd.so LoadModule dir_module modules/mod_dir.so User daemon Group daemon AllowOverride none Require all denied DocumentRoot \"/usr/local/apache2/htdocs\" Options Indexes FollowSymLinks Includes AllowOverride None Require all granted SetEnvIf X-Remote-User \"(.*)\" REMOTE_USER=$0 SetEnvIf X-Remote-User-Name \"(.*)\" REMOTE_USER_NAME=$0 SetEnvIf X-Remote-User-Email \"(.*)\" REMOTE_USER_EMAIL=$0 DirectoryIndex index.html Require all denied ErrorLog /proc/self/fd/2 LogLevel warn LogFormat \"%h %l %u %t \\\"%r\\\" %>s %b \\\"%{Referer}i\\\" \\\"%{User-Agent}i\\\"\" combined LogFormat \"%h %l %u %t \\\"%r\\\" %>s %b\" common CustomLog /proc/self/fd/1 common TypesConfig conf/mime.types AddType application/x-compress .Z AddType application/x-gzip .gz .tgz AddType text/html .shtml AddOutputFilter INCLUDES .shtml user.shtml Hello User

              Hello !

              You authenticated as:

              Your email address is:

              Environment:

              !

              index.html Hello World

              Hello world!

              Dockerfile FROM httpd:2.4.54@sha256:c9eba4494b9d856843b49eb897f9a583a0873b1c14c86d5ab77e5bdedd6ad05d # \"Created\": \"2022-06-08T18:45:46.260791323Z\" , \"Version\":\"2.4.54\" RUN apt-get update \\ && apt-get install -y --no-install-recommends wget ca-certificates libcjose0 libhiredis0.14 apache2-api-20120211 apache2-bin\\ && wget https://github.com/zmartzone/mod_auth_openidc/releases/download/v2.4.11.2/libapache2-mod-auth-openidc_2.4.11.2-1.buster+1_amd64.deb \\ && dpkg -i libapache2-mod-auth-openidc_2.4.11.2-1.buster+1_amd64.deb \\ && ln -s /usr/lib/apache2/modules/mod_auth_openidc.so /usr/local/apache2/modules/mod_auth_openidc.so \\ && rm -rf /var/log/dpkg.log /var/log/alternatives.log /var/log/apt \\ && touch /usr/local/apache2/conf/extra/secret.conf \\ && touch /usr/local/apache2/conf/extra/oidc.conf RUN echo \"\\n\\nLoadModule auth_openidc_module modules/mod_auth_openidc.so\\n\\nInclude conf/extra/secret.conf\\nInclude conf/extra/oidc.conf\\n\" >> /usr/local/apache2/conf/httpd.conf gluu.secret.conf OIDCClientID OIDCCryptoPassphrase OIDCClientSecret OIDCResponseType code OIDCScope \"openid email profile\" OIDCProviderTokenEndpointAuth client_secret_basic OIDCSSLValidateServer Off OIDCRedirectURI http://localhost:8111/oauth2callback OIDCCryptoPassphrase Require valid-user AuthType openid-connect After, run an Apache container which will play the role of an application being protected by the authenticating reverse proxy. docker run -dit -p 8110:80 \\ -v \"$PWD/app.conf\":/usr/local/apache2/conf/httpd.conf \\ -v \"$PWD/index.html\":/usr/local/apache2/htdocs/index.html \\ -v \"$PWD/user.shtml\":/usr/local/apache2/htdocs/user.shtml \\ --name apache-app httpd:2.4 Note that we are using a popular pre-built image useful for acting as a reverse proxy for authentication in front of an application. It contains a stripped-down Apache with minimal modules, and adds the mod_auth_openidc module for performing OpenID Connect authentication. Make a test curl command call to ensure you get back some content as shown in the screenshot below curl http://localhost:8110/user.shtml","title":"Create an Application Container"},{"location":"admin/recipes/getting-started-rancher/#create-an-authenticating-reverse-proxy-container","text":"We shall use Apache, but this time we use a Docker image that has mod_auth_oidc installed and configured. This proxy will require authentication, handle the authentication flow with redirects, and then forward requests to the application. In order to use this, you will need to have registered a new OpenID Connect client on the Janssen server. We did that in the step 1 above Add the following files to the test folder. oidc.conf # Unset to make sure clients can't control these RequestHeader unset X-Remote-User RequestHeader unset X-Remote-User-Name RequestHeader unset X-Remote-User-Email # If you want to see tons of logs for your experimentation #LogLevel trace8 OIDCClientID OIDCProviderMetadataURL https://idp-proxy.med.stanford.edu/auth/realms/med-all/.well-known/openid-configuration #OIDCProviderMetadataURL https://idp-proxy-stage.med.stanford.edu/auth/realms/choir/.well-known/openid-configuration OIDCRedirectURI http://localhost:8111/oauth2callback OIDCScope \"openid email profile\" OIDCRemoteUserClaim principal OIDCPassClaimsAs environment AuthType openid-connect Require valid-user ProxyPass http://app:80/ ProxyPassReverse http://app:80/ RequestHeader set X-Remote-User %{OIDC_CLAIM_principal}e RequestHeader set X-Remote-User-Name %{OIDC_CLAIM_name}e RequestHeader set X-Remote-User-Email %{OIDC_CLAIM_email}e proxy.conf # This is the main Apache HTTP server configuration file. For documentation, see: # http://httpd.apache.org/docs/2.4/ # http://httpd.apache.org/docs/2.4/mod/directives.html # # This is intended to be a hardened configuration, with minimal security surface area necessary # to run mod_auth_openidc. ServerRoot \"/usr/local/apache2\" Listen 80 LoadModule mpm_event_module modules/mod_mpm_event.so LoadModule authn_file_module modules/mod_authn_file.so LoadModule authn_core_module modules/mod_authn_core.so LoadModule authz_host_module modules/mod_authz_host.so LoadModule authz_groupfile_module modules/mod_authz_groupfile.so LoadModule authz_user_module modules/mod_authz_user.so LoadModule authz_core_module modules/mod_authz_core.so LoadModule access_compat_module modules/mod_access_compat.so LoadModule auth_basic_module modules/mod_auth_basic.so LoadModule reqtimeout_module modules/mod_reqtimeout.so LoadModule filter_module modules/mod_filter.so LoadModule mime_module modules/mod_mime.so LoadModule log_config_module modules/mod_log_config.so LoadModule env_module modules/mod_env.so LoadModule headers_module modules/mod_headers.so LoadModule setenvif_module modules/mod_setenvif.so #LoadModule version_module modules/mod_version.so LoadModule proxy_module modules/mod_proxy.so LoadModule proxy_http_module modules/mod_proxy_http.so LoadModule unixd_module modules/mod_unixd.so #LoadModule status_module modules/mod_status.so #LoadModule autoindex_module modules/mod_autoindex.so LoadModule dir_module modules/mod_dir.so LoadModule alias_module modules/mod_alias.so User daemon Group daemon ServerAdmin you@example.com AllowOverride none Require all denied DocumentRoot \"/usr/local/apache2/htdocs\" Options Indexes FollowSymLinks AllowOverride None Require all granted DirectoryIndex index.html Options None Require all denied Require all denied ErrorLog /proc/self/fd/2 LogLevel warn LogFormat \"%h %l %u %t \\\"%r\\\" %>s %b \\\"%{Referer}i\\\" \\\"%{User-Agent}i\\\"\" combined LogFormat \"%h %l %u %t \\\"%r\\\" %>s %b\" common LogFormat \"%h %l %u %t \\\"%r\\\" %>s %b \\\"%{Referer}i\\\" \\\"%{User-Agent}i\\\" %I %O\" combinedio CustomLog /proc/self/fd/1 common ScriptAlias /cgi-bin/ \"/usr/local/apache2/cgi-bin/\" AllowOverride None Options None Require all granted RequestHeader unset Proxy early TypesConfig conf/mime.types AddType application/x-compress .Z AddType application/x-gzip .gz .tgz Include conf/extra/proxy-html.conf SSLRandomSeed startup builtin SSLRandomSeed connect builtin TraceEnable off ServerTokens Prod ServerSignature Off LoadModule auth_openidc_module modules/mod_auth_openidc.so Include conf/extra/secret.conf Include conf/extra/oidc.conf Edit the file to include the client secret for the client you created during DCR, and add a securely generated pass phrase for the session keys docker build --pull -t apache-oidc -f Dockerfile . docker run -dit -p 8111:80 \\ -v \"$PWD/proxy.conf\":/usr/local/apache2/conf/httpd.conf \\ -v \"$PWD/gluu.secret.conf\":/usr/local/apache2/conf/extra/secret.conf \\ -v \"$PWD/oidc.conf\":/usr/local/apache2/conf/extra/oidc.conf \\ --link apache-app:app \\ --name apache-proxy apache-oidc Now open a fresh web browser with private (incognito) mode, and go to this url http://localhost:8111/user.shtml To check the proxy logs docker logs -f apache-proxy To see the app logs docker logs -f apache-app If you modified the configuration files, just restart the proxy. docker restart apache-proxy","title":"Create an Authenticating Reverse Proxy Container"},{"location":"admin/saml/","text":"Where is this content? # The Gluu Flex documentation is a work in progress, and this document is currently a draft. Keep an eye on this page for updates.","title":"Index"},{"location":"admin/saml/#where-is-this-content","text":"The Gluu Flex documentation is a work in progress, and this document is currently a draft. Keep an eye on this page for updates.","title":"Where is this content?"},{"location":"admin/saml/idp/","text":"Where is this content? # The Gluu Flex documentation is a work in progress, and this document is currently a draft. Keep an eye on this page for updates.","title":"Idp"},{"location":"admin/saml/idp/#where-is-this-content","text":"The Gluu Flex documentation is a work in progress, and this document is currently a draft. Keep an eye on this page for updates.","title":"Where is this content?"},{"location":"admin/saml/proxy/","text":"Where is this content? # The Gluu Flex documentation is a work in progress, and this document is currently a draft. Keep an eye on this page for updates.","title":"Proxy"},{"location":"admin/saml/proxy/#where-is-this-content","text":"The Gluu Flex documentation is a work in progress, and this document is currently a draft. Keep an eye on this page for updates.","title":"Where is this content?"},{"location":"includes/cn-system-requirements/","text":"The resources may be set minimally to the below: 8-13 GB RAM based on the services deployed 8-11 CPU cores based on the services deployed 50GB hard-disk Use the listing below for a detailed estimation of the minimum required resources. The table contains the default resources recommendation per service. Depending on the use of each service the resources need may be increase or decrease. Service CPU Unit RAM Disk Space Processor Type Required Auth server 2.5 2.5GB N/A 64 Bit Yes fido2 0.5 0.5GB N/A 64 Bit No scim 1 1GB N/A 64 Bit No config - job 0.3 0.3GB N/A 64 Bit Yes on fresh installs persistence - job 0.3 0.3GB N/A 64 Bit Yes on fresh installs nginx 1 1GB N/A 64 Bit Yes if ALB/Istio not used auth-key-rotation 0.3 0.3GB N/A 64 Bit No [Strongly recommended] config-api 1 1GB N/A 64 Bit No casa 0.5 0.5GB N/A 64 Bit No admin-ui 2 2GB N/A 64 Bit No link 0.5 1GB N/A 64 Bit No saml 0.5 1GB N/A 64 Bit No Releases of images are in style 1.0.0-beta.0, 1.0.0-0","title":"Cn system requirements"},{"location":"install/","tags":["administration","installation"],"text":"Installation Overview # The goal of Gluu Flex is to give you a lot of deployment options. This is a challenge--the more ways to install, the more ways for things to go wrong! But to build a large community, we need to provide ways to install the software in enough different ways to make at least the bulk of the community happy. Currently, that means the following installation options: VM packages for Ubuntu, SUSE and Red Hat Helm deployments for Amazon, Google, Microsoft and Rancher Docker monolith deployment for development / testing (not production) Minimal Configuration # It turns out that just installing the Flex binary object code (i.e. the bits), is totally useless. That's because in order to do anything useful with Gluu Flex, you need a minimal amount of configuration. For example, you need to generate cryptographic key pairs, you need to generate a minimal amount of data in the database, you need to generate some web server TLS certificates. For this reason, for most of the platforms, installation is a three step process. Step 1, install the bits. Step 2, run \"setup\" and answer some basic question (like the hostname of your IDP). Step 3, fire up a configuration tool to perform any other last mile configuration. Databases # Gluu Flex gives you a few options to store data: MySQL, Postgres, Couchbase, Amazon Aurora, and Spanner. You can also configure an in-memory cache server like Redis. Sometimes installation and configuration of this database is included in the setup process. Sometimes, you need to setup the database ahead of time. Please refer to the database instructions specific for your choice. And of course, you may need to refer to the database documentation itself--we don't want to duplicate any of that third party content. Optimization # Remember, installation is just a starting point. To get peak performance, you may need to tweak some of the configuration dials for your system or the database. If you intend to deploy a Gluu Flex in production for high concurrency, make sure you benchmark the exact flows you expect to serve in production.","title":"Installation Overview"},{"location":"install/#installation-overview","text":"The goal of Gluu Flex is to give you a lot of deployment options. This is a challenge--the more ways to install, the more ways for things to go wrong! But to build a large community, we need to provide ways to install the software in enough different ways to make at least the bulk of the community happy. Currently, that means the following installation options: VM packages for Ubuntu, SUSE and Red Hat Helm deployments for Amazon, Google, Microsoft and Rancher Docker monolith deployment for development / testing (not production)","title":"Installation Overview"},{"location":"install/#minimal-configuration","text":"It turns out that just installing the Flex binary object code (i.e. the bits), is totally useless. That's because in order to do anything useful with Gluu Flex, you need a minimal amount of configuration. For example, you need to generate cryptographic key pairs, you need to generate a minimal amount of data in the database, you need to generate some web server TLS certificates. For this reason, for most of the platforms, installation is a three step process. Step 1, install the bits. Step 2, run \"setup\" and answer some basic question (like the hostname of your IDP). Step 3, fire up a configuration tool to perform any other last mile configuration.","title":"Minimal Configuration"},{"location":"install/#databases","text":"Gluu Flex gives you a few options to store data: MySQL, Postgres, Couchbase, Amazon Aurora, and Spanner. You can also configure an in-memory cache server like Redis. Sometimes installation and configuration of this database is included in the setup process. Sometimes, you need to setup the database ahead of time. Please refer to the database instructions specific for your choice. And of course, you may need to refer to the database documentation itself--we don't want to duplicate any of that third party content.","title":"Databases"},{"location":"install/#optimization","text":"Remember, installation is just a starting point. To get peak performance, you may need to tweak some of the configuration dials for your system or the database. If you intend to deploy a Gluu Flex in production for high concurrency, make sure you benchmark the exact flows you expect to serve in production.","title":"Optimization"},{"location":"install/agama/prerequisites/","tags":["administration","installation"],"text":"Agama Lab # Agama Lab is a platform to manage your Gluu license. This is where you may subscribe to Gluu Flex or obtain credentials for your enterprise license. To begin, please visit Agama Lab You may register via email or login via GitHub If you want to author or test Agama projects, you will need to login via GitHub Once you have logged in, please navigate to Market > SCAN and subscribe to the free tier. SCAN is the API gateway Gluu uses to validate licenses. The free tier will give you 500 credits. As license calls do not cost credits, this will not cost you anything. Software Statement Assertions # In order to install Flex, you will need a Software Statement Assertion (SSA). An SSA is a signed JSON Web Token (JWT) that is required by the Flex install script to validate your license. Obtaining an SSA # Gluu issues SSAs through the Agama Lab web interface. You can obtain an SSA for use with Flex by following these steps: Login to Agama Lab On the left navigation bar, select Market Navigate to the tab named SSA . Sign up for a free SCAN subscription, which will give you 500 SCAN credits. Flex does not cost any SCAN credits, so you will not be charged for SCAN. Click on Create New SSA On Software Name , fill in a unique identifier for this SSA Description is optional Under Software Roles , tick license Under Expiration Date , select an appropriate date. Your SSA will not be useable after that date. Under SSA Lifetime , choose an appropriate lifetime for the Flex client. One month or longer is recommended. Deselect One time use and Rotate SSA Click Create - Click on Detail of the newly issued SSA, then click on Show JWT You will be shown a long string of characters. Copy this and save it to a file. You may now use this file during Flex installation. License # Gluu Flex uses the SSA obtained in the above step to either request a 30 day trial license or verify presence of a license tied to your Agama Lab account. One account may request one trial license in its lifetime. To purchase a full license, please navigate to the Flex tab of the marketplace where you may purchase licenses for up to 1600 MAU (monthly active users). To purchase an enterprise license for more MAU, please contact Sales . If you have subscribed to Flex via Agama Lab, the SSA obtained in the step before will automatically link your license to your installation. For enterprise licenses, please open a support ticket so that we can issue a license against your Agama account. Once this is done, you may use the SSA obtained to proceed to installation.","title":"Prerequisites"},{"location":"install/agama/prerequisites/#agama-lab","text":"Agama Lab is a platform to manage your Gluu license. This is where you may subscribe to Gluu Flex or obtain credentials for your enterprise license. To begin, please visit Agama Lab You may register via email or login via GitHub If you want to author or test Agama projects, you will need to login via GitHub Once you have logged in, please navigate to Market > SCAN and subscribe to the free tier. SCAN is the API gateway Gluu uses to validate licenses. The free tier will give you 500 credits. As license calls do not cost credits, this will not cost you anything.","title":"Agama Lab"},{"location":"install/agama/prerequisites/#software-statement-assertions","text":"In order to install Flex, you will need a Software Statement Assertion (SSA). An SSA is a signed JSON Web Token (JWT) that is required by the Flex install script to validate your license.","title":"Software Statement Assertions"},{"location":"install/agama/prerequisites/#obtaining-an-ssa","text":"Gluu issues SSAs through the Agama Lab web interface. You can obtain an SSA for use with Flex by following these steps: Login to Agama Lab On the left navigation bar, select Market Navigate to the tab named SSA . Sign up for a free SCAN subscription, which will give you 500 SCAN credits. Flex does not cost any SCAN credits, so you will not be charged for SCAN. Click on Create New SSA On Software Name , fill in a unique identifier for this SSA Description is optional Under Software Roles , tick license Under Expiration Date , select an appropriate date. Your SSA will not be useable after that date. Under SSA Lifetime , choose an appropriate lifetime for the Flex client. One month or longer is recommended. Deselect One time use and Rotate SSA Click Create - Click on Detail of the newly issued SSA, then click on Show JWT You will be shown a long string of characters. Copy this and save it to a file. You may now use this file during Flex installation.","title":"Obtaining an SSA"},{"location":"install/agama/prerequisites/#license","text":"Gluu Flex uses the SSA obtained in the above step to either request a 30 day trial license or verify presence of a license tied to your Agama Lab account. One account may request one trial license in its lifetime. To purchase a full license, please navigate to the Flex tab of the marketplace where you may purchase licenses for up to 1600 MAU (monthly active users). To purchase an enterprise license for more MAU, please contact Sales . If you have subscribed to Flex via Agama Lab, the SSA obtained in the step before will automatically link your license to your installation. For enterprise licenses, please open a support ticket so that we can issue a license against your Agama account. Once this is done, you may use the SSA obtained to proceed to installation.","title":"License"},{"location":"install/docker-install/compose/","tags":["administration","reference","kubernetes","docker image","docker compose"],"text":"Warning This image is for testing and development purposes only. Use Flex helm charts for production setups. Overview # Docker monolith image packaging for Gluu Flex. This image packs janssen services including the auth-server, config-api, fido2, casa, scim and the Gluu admin ui. Pre-requisites # Docker Docker compose Versions # See Releases for stable versions. This image should never be used in production. For bleeding-edge/unstable version, use gluufederation/monolith:5.0.0_dev . Environment Variables # Installation depends on the set of environment variables shown below. These environment variables can be set to customize installation as per the need. If not set, the installer uses default values. ENV Description Default CN_HOSTNAME Hostname to install gluu with. demoexample.gluu.org CN_ADMIN_PASS Password of the admin user. 1t5Fin3#security CN_ORG_NAME Organization name. Used for ssl cert generation. Gluu CN_EMAIL Email. Used for ssl cert generation. team@gluu.org CN_CITY City. Used for ssl cert generation. Austin CN_STATE State. Used for ssl cert generation TX CN_COUNTRY Country. Used for ssl cert generation. US CN_INSTALL_MYSQL Install gluu with mysql as the backend false CN_INSTALL_PGSQL Install gluu with Postgres as the backend false CN_INSTALL_ADMIN_UI Installs the Admin-UI true CN_INSTALL_CONFIG_API Installs the Config API service. true CN_INSTALL_SCIM Installs the SCIM API service. true CN_INSTALL_FIDO2 Installs the FIDO2 API service. true RDBMS_DATABASE RDBMS gluu database for MySQL or Postgres. gluu RDBMS_USER RDBMS database user for MySQL or Postgres. gluu RDBMS_PASSWORD RDBMS database user password for MySQL or Postgres. 1t5Fin3#security RDBMS_HOST RDBMS host for MySQL or Postgres. mysql which is the docker compose service name TEST_CLIENT_ID ID of test client in UUID which has all available scopes to access any gluu API 9876baac-de39-4c23-8a78-674b59df8c09 TEST_CLIENT_SECRET Secret for test client 1t5Fin3#security TEST_CLIENT_TRUSTED Trust test client true TEST_CLIENT_REDIRECT_URI Not Implemented yet Redirect URI for test client. Multiple uri's with comma may be provided, if not provided redirect uris will be same as the config-api-client `` How to run # Download the compose file of your chosen persistence from mysql or postgres wget https://raw.githubusercontent.com/GluuFederation/flex/main/docker-flex-monolith/flex-mysql-compose.yml wget https://raw.githubusercontent.com/GluuFederation/flex/main/docker-flex-monolith/flex-postgres-compose.yml Download the script files wget https://raw.githubusercontent.com/GluuFederation/flex/main/docker-flex-monolith/up.sh wget https://raw.githubusercontent.com/GluuFederation/flex/main/docker-flex-monolith/down.sh wget https://raw.githubusercontent.com/GluuFederation/flex/main/docker-flex-monolith/clean.sh Give execute permission to the scripts chmod u+x up.sh down.sh clean.sh This docker compose file runs two containers, the flex monolith container and mysql container. To start the containers. ./up.sh #You can pass mysql|postgres as an argument to the script. If you don't pass any, it will default to mysql. To view the containers running docker compose -f flex-mysql-compose.yml ps To stop the containers. ./down.sh #You can pass mysql|postgres as an argument to the script. If you don't pass any, it will default to mysql. Configure Gluu flex # Access the Docker container shell using: docker compose -f flex-mysql-compose.yml exec flex /bin/bash #This opens a bash terminal in the running container You can grab client_id and client_pw (secret), and other values from setup.properties or /opt/jans/jans-setup/setup.properties.last Use the CLI tools located under /opt/jans/jans-cli/ to configure Gluu flex as needed. For example you can run the TUI : python3 /opt/jans/jans-cli/config-cli-tui.py Access endpoints externally # Add to your /etc/hosts file the ip domain record which should be the ip of the instance docker is installed at and the domain used in the env above CN_HOSTNAME . # For-example 172 .22.0.3 demoexample.gluu.org After adding the record you can hit endpoints such as https://demoexample.gluu.org/.well-known/openid-configuration Clean up # Remove setup and volumes ./clean.sh #You can pass mysql|postgres as an argument to the script. If you don't pass any, it will default to mysql.","title":"Docker compose"},{"location":"install/docker-install/compose/#overview","text":"Docker monolith image packaging for Gluu Flex. This image packs janssen services including the auth-server, config-api, fido2, casa, scim and the Gluu admin ui.","title":"Overview"},{"location":"install/docker-install/compose/#pre-requisites","text":"Docker Docker compose","title":"Pre-requisites"},{"location":"install/docker-install/compose/#versions","text":"See Releases for stable versions. This image should never be used in production. For bleeding-edge/unstable version, use gluufederation/monolith:5.0.0_dev .","title":"Versions"},{"location":"install/docker-install/compose/#environment-variables","text":"Installation depends on the set of environment variables shown below. These environment variables can be set to customize installation as per the need. If not set, the installer uses default values. ENV Description Default CN_HOSTNAME Hostname to install gluu with. demoexample.gluu.org CN_ADMIN_PASS Password of the admin user. 1t5Fin3#security CN_ORG_NAME Organization name. Used for ssl cert generation. Gluu CN_EMAIL Email. Used for ssl cert generation. team@gluu.org CN_CITY City. Used for ssl cert generation. Austin CN_STATE State. Used for ssl cert generation TX CN_COUNTRY Country. Used for ssl cert generation. US CN_INSTALL_MYSQL Install gluu with mysql as the backend false CN_INSTALL_PGSQL Install gluu with Postgres as the backend false CN_INSTALL_ADMIN_UI Installs the Admin-UI true CN_INSTALL_CONFIG_API Installs the Config API service. true CN_INSTALL_SCIM Installs the SCIM API service. true CN_INSTALL_FIDO2 Installs the FIDO2 API service. true RDBMS_DATABASE RDBMS gluu database for MySQL or Postgres. gluu RDBMS_USER RDBMS database user for MySQL or Postgres. gluu RDBMS_PASSWORD RDBMS database user password for MySQL or Postgres. 1t5Fin3#security RDBMS_HOST RDBMS host for MySQL or Postgres. mysql which is the docker compose service name TEST_CLIENT_ID ID of test client in UUID which has all available scopes to access any gluu API 9876baac-de39-4c23-8a78-674b59df8c09 TEST_CLIENT_SECRET Secret for test client 1t5Fin3#security TEST_CLIENT_TRUSTED Trust test client true TEST_CLIENT_REDIRECT_URI Not Implemented yet Redirect URI for test client. Multiple uri's with comma may be provided, if not provided redirect uris will be same as the config-api-client ``","title":"Environment Variables"},{"location":"install/docker-install/compose/#how-to-run","text":"Download the compose file of your chosen persistence from mysql or postgres wget https://raw.githubusercontent.com/GluuFederation/flex/main/docker-flex-monolith/flex-mysql-compose.yml wget https://raw.githubusercontent.com/GluuFederation/flex/main/docker-flex-monolith/flex-postgres-compose.yml Download the script files wget https://raw.githubusercontent.com/GluuFederation/flex/main/docker-flex-monolith/up.sh wget https://raw.githubusercontent.com/GluuFederation/flex/main/docker-flex-monolith/down.sh wget https://raw.githubusercontent.com/GluuFederation/flex/main/docker-flex-monolith/clean.sh Give execute permission to the scripts chmod u+x up.sh down.sh clean.sh This docker compose file runs two containers, the flex monolith container and mysql container. To start the containers. ./up.sh #You can pass mysql|postgres as an argument to the script. If you don't pass any, it will default to mysql. To view the containers running docker compose -f flex-mysql-compose.yml ps To stop the containers. ./down.sh #You can pass mysql|postgres as an argument to the script. If you don't pass any, it will default to mysql.","title":"How to run"},{"location":"install/docker-install/compose/#configure-gluu-flex","text":"Access the Docker container shell using: docker compose -f flex-mysql-compose.yml exec flex /bin/bash #This opens a bash terminal in the running container You can grab client_id and client_pw (secret), and other values from setup.properties or /opt/jans/jans-setup/setup.properties.last Use the CLI tools located under /opt/jans/jans-cli/ to configure Gluu flex as needed. For example you can run the TUI : python3 /opt/jans/jans-cli/config-cli-tui.py","title":"Configure Gluu flex"},{"location":"install/docker-install/compose/#access-endpoints-externally","text":"Add to your /etc/hosts file the ip domain record which should be the ip of the instance docker is installed at and the domain used in the env above CN_HOSTNAME . # For-example 172 .22.0.3 demoexample.gluu.org After adding the record you can hit endpoints such as https://demoexample.gluu.org/.well-known/openid-configuration","title":"Access endpoints externally"},{"location":"install/docker-install/compose/#clean-up","text":"Remove setup and volumes ./clean.sh #You can pass mysql|postgres as an argument to the script. If you don't pass any, it will default to mysql.","title":"Clean up"},{"location":"install/docker-install/quick-start/","tags":["administration","installation","quick-start","docker"],"text":"Warning This image is for testing and development purposes only. Use Flex helm charts for production setups. Overview # The quickest way to get Gluu flex up and running is to have a Docker container-based deployment. System Requirements # System should meet minimum VM system requirements Install # Installation depends on a set of environment variables . These environment variables can be set to customize installation as per the need. If not set, the installer uses default values. Run this command to start the installation: wget https://raw.githubusercontent.com/GluuFederation/flex/v5.1.6.nightly/automation/startflexmonolithdemo.sh && chmod u+x startflexmonolithdemo.sh && sudo bash startflexmonolithdemo.sh demoexample.gluu.org MYSQL Console messages like below confirms the successful installation: [+] Running 3/3 \u283f Network docker-flex-monolith_cloud_bridge Created 0.0s \u283f Container docker-flex-monolith-mysql-1 Started 0.6s \u283f Container docker-flex-monolith-flex-1 Started 0.9s Waiting for auth-server to come up. Depending on the resources it may take 3-5 mins for the services to be up. Testing openid-configuration endpoint.. As can be seen, the install script also accesses the well-known endpoints to verify that Gluu Flex is responsive. Verify Installation By Accessing Standard Endpoints # To access Gluu flex standard endpoints from outside of the Docker container, systems /etc/hosts file needs to be updated. Open the file and add the IP domain record which should be the IP of the instance docker is installed. And the domain used in the env above CN_HOSTNAME . # For-example 172 .22.0.3 demoexample.gluu.org After adding the record, hit the standard endpoints such as https://demoexample.gluu.org/.well-known/openid-configuration Configure Gluu flex # Access the Docker container shell using: docker exec -ti docker-flex-monolith-flex-1 bash Grab a pair of client_id and client_pw(secret) from setup.properties or /opt/jans/jans-setup/setup.properties.last Use the CLI tools located under /opt/jans/jans-cli/ to configure Gluu flex as needed. For example you can run the TUI : python3 /opt/jans/jans-cli/config-cli-tui.py Uninstall/Remove Gluu flex # This docker based installation uses docker compose under the hood to create containers. Hence uninstalling Gluu flex involves invoking docker compose with appropriate yml file. Run command below to stop and remove containers. docker compose -f /tmp/flex/docker-flex-monolith/flex-mysql-compose.yml down && rm -rf flex-* Console messages like below confirms the successful removal: [+] Running 3/3 \u283f Container docker-flex-monolith-flex-1 Removed 10.5s \u283f Container docker-flex-monolith-mysql-1 Removed 0.9s \u283f Network docker-flex-monolith_cloud_bridge Removed 0.1s","title":"Quick Start"},{"location":"install/docker-install/quick-start/#overview","text":"The quickest way to get Gluu flex up and running is to have a Docker container-based deployment.","title":"Overview"},{"location":"install/docker-install/quick-start/#system-requirements","text":"System should meet minimum VM system requirements","title":"System Requirements"},{"location":"install/docker-install/quick-start/#install","text":"Installation depends on a set of environment variables . These environment variables can be set to customize installation as per the need. If not set, the installer uses default values. Run this command to start the installation: wget https://raw.githubusercontent.com/GluuFederation/flex/v5.1.6.nightly/automation/startflexmonolithdemo.sh && chmod u+x startflexmonolithdemo.sh && sudo bash startflexmonolithdemo.sh demoexample.gluu.org MYSQL Console messages like below confirms the successful installation: [+] Running 3/3 \u283f Network docker-flex-monolith_cloud_bridge Created 0.0s \u283f Container docker-flex-monolith-mysql-1 Started 0.6s \u283f Container docker-flex-monolith-flex-1 Started 0.9s Waiting for auth-server to come up. Depending on the resources it may take 3-5 mins for the services to be up. Testing openid-configuration endpoint.. As can be seen, the install script also accesses the well-known endpoints to verify that Gluu Flex is responsive.","title":"Install"},{"location":"install/docker-install/quick-start/#verify-installation-by-accessing-standard-endpoints","text":"To access Gluu flex standard endpoints from outside of the Docker container, systems /etc/hosts file needs to be updated. Open the file and add the IP domain record which should be the IP of the instance docker is installed. And the domain used in the env above CN_HOSTNAME . # For-example 172 .22.0.3 demoexample.gluu.org After adding the record, hit the standard endpoints such as https://demoexample.gluu.org/.well-known/openid-configuration","title":"Verify Installation By Accessing Standard Endpoints"},{"location":"install/docker-install/quick-start/#configure-gluu-flex","text":"Access the Docker container shell using: docker exec -ti docker-flex-monolith-flex-1 bash Grab a pair of client_id and client_pw(secret) from setup.properties or /opt/jans/jans-setup/setup.properties.last Use the CLI tools located under /opt/jans/jans-cli/ to configure Gluu flex as needed. For example you can run the TUI : python3 /opt/jans/jans-cli/config-cli-tui.py","title":"Configure Gluu flex"},{"location":"install/docker-install/quick-start/#uninstallremove-gluu-flex","text":"This docker based installation uses docker compose under the hood to create containers. Hence uninstalling Gluu flex involves invoking docker compose with appropriate yml file. Run command below to stop and remove containers. docker compose -f /tmp/flex/docker-flex-monolith/flex-mysql-compose.yml down && rm -rf flex-* Console messages like below confirms the successful removal: [+] Running 3/3 \u283f Container docker-flex-monolith-flex-1 Removed 10.5s \u283f Container docker-flex-monolith-mysql-1 Removed 0.9s \u283f Network docker-flex-monolith_cloud_bridge Removed 0.1s","title":"Uninstall/Remove Gluu flex"},{"location":"install/helm-install/","tags":["administration","installation","helm"],"text":"Overview # Gluu Flex enables organizations to build a scalable centralized authentication and authorization service using free open source software. The components of the project include client and server implementations of the OAuth, OpenID Connect, SCIM and FIDO standards. All these components are deployed using Gluu helm chart . You can check the reference guide to view the list of the chart components and values. Looking for older helm charts? # If you are looking for older helm charts, you need to build them from the Gluu Flex repository. We only keep the last 5 versions of the chart up. We support auto-upgrade using helm upgrade and hence want everyone to stay up to date with our charts. To build older charts manually from the Gluu Flex repository, you can use the following example which assumes we are building for janssen version v5.0.0 : git clone --filter blob:none --no-checkout https://github.com/GluuFederation/flex.git /tmp/flex \\ && cd /tmp/flex \\ && git sparse-checkout init --cone \\ && git checkout v5.0.0 \\ && git sparse-checkout add charts/gluu \\ && cd charts/gluu \\ && helm dependency update \\ && helm package .","title":"Overview"},{"location":"install/helm-install/#overview","text":"Gluu Flex enables organizations to build a scalable centralized authentication and authorization service using free open source software. The components of the project include client and server implementations of the OAuth, OpenID Connect, SCIM and FIDO standards. All these components are deployed using Gluu helm chart . You can check the reference guide to view the list of the chart components and values.","title":"Overview"},{"location":"install/helm-install/#looking-for-older-helm-charts","text":"If you are looking for older helm charts, you need to build them from the Gluu Flex repository. We only keep the last 5 versions of the chart up. We support auto-upgrade using helm upgrade and hence want everyone to stay up to date with our charts. To build older charts manually from the Gluu Flex repository, you can use the following example which assumes we are building for janssen version v5.0.0 : git clone --filter blob:none --no-checkout https://github.com/GluuFederation/flex.git /tmp/flex \\ && cd /tmp/flex \\ && git sparse-checkout init --cone \\ && git checkout v5.0.0 \\ && git sparse-checkout add charts/gluu \\ && cd charts/gluu \\ && helm dependency update \\ && helm package .","title":"Looking for older helm charts?"},{"location":"install/helm-install/amazon-eks/","tags":["administration","installation","helm","EKS","Amazon Web Services","AWS"],"text":"Install Gluu Flex on EKS # System Requirements # The resources may be set minimally to the below: 8-13 GB RAM based on the services deployed 8-11 CPU cores based on the services deployed 50GB hard-disk Use the listing below for a detailed estimation of the minimum required resources. The table contains the default resources recommendation per service. Depending on the use of each service the resources need may be increase or decrease. Service CPU Unit RAM Disk Space Processor Type Required Auth server 2.5 2.5GB N/A 64 Bit Yes fido2 0.5 0.5GB N/A 64 Bit No scim 1 1GB N/A 64 Bit No config - job 0.3 0.3GB N/A 64 Bit Yes on fresh installs persistence - job 0.3 0.3GB N/A 64 Bit Yes on fresh installs nginx 1 1GB N/A 64 Bit Yes if ALB/Istio not used auth-key-rotation 0.3 0.3GB N/A 64 Bit No [Strongly recommended] config-api 1 1GB N/A 64 Bit No casa 0.5 0.5GB N/A 64 Bit No admin-ui 2 2GB N/A 64 Bit No link 0.5 1GB N/A 64 Bit No saml 0.5 1GB N/A 64 Bit No Releases of images are in style 1.0.0-beta.0, 1.0.0-0 Initial Setup # Before initiating the setup, please obtain an SSA for Flex trial, after which you will issued a JWT. Install aws cli Configure your AWS user account using aws configure command. This makes you able to authenticate before creating the cluster. Note that this user account must have permissions to work with Amazon EKS IAM roles and service linked roles, AWS CloudFormation, and a VPC and related resources Install kubectl Install eksctl Create cluster using eksctl such as the following example: eksctl create cluster --name gluu-cluster --nodegroup-name gluu-nodes --node-type NODE_TYPE --nodes 2 --managed --region REGION_CODE You can adjust node-type and nodes number as per your desired cluster size To be able to attach volumes to your pod, you need to install the Amazon EBS CSI driver Install Helm3 Create gluu namespace where our resources will reside kubectl create namespace gluu Gluu Flex Installation using Helm # Install Nginx-Ingress , if you are not using Istio ingress helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx helm repo add stable https://charts.helm.sh/stable helm repo update helm install nginx ingress-nginx/ingress-nginx Create a file named override.yaml and add changes as per your desired configuration: FQDN/domain is not registered: Get the Loadbalancer address: kubectl get svc nginx-ingress-nginx-controller --output jsonpath='{.status.loadBalancer.ingress[0].hostname}' Add the following yaml snippet to your override.yaml file: global : isFqdnRegistered : false config : configmap : lbAddr : http:// #Add LB address from previous command FQDN/domain is registered: Add the following yaml snippet to your override.yaml file: global : isFqdnRegistered : true fqdn : demoexample.gluu.org #CHANGE-THIS to the FQDN used for Gluu config : configmap : lbAddr : http:// #Add LB address from previous command nginx : ingress : enabled : true path : / hosts : - demoexample.gluu.org #CHANGE-THIS to the FQDN used for Gluu tls : - secretName : tls-certificate hosts : - demoexample.gluu.org #CHANGE-THIS to the FQDN used for Gluu Couchbase for pesistence storage Add the following yaml snippet to your override.yaml file: global : cnPersistenceType : couchbase config : configmap : # The prefix of couchbase buckets. This helps with separation in between different environments and allows for the same couchbase cluster to be used by different setups of Janssen. cnCouchbaseBucketPrefix : jans # -- Couchbase certificate authority string. This must be encoded using base64. This can also be found in your couchbase UI Security > Root Certificate. In mTLS setups this is not required. cnCouchbaseCrt : SWFtTm90YVNlcnZpY2VBY2NvdW50Q2hhbmdlTWV0b09uZQo= # -- The number of replicas per index created. Please note that the number of index nodes must be one greater than the number of index replicas. That means if your couchbase cluster only has 2 index nodes you cannot place the number of replicas to be higher than 1. cnCouchbaseIndexNumReplica : 0 # -- Couchbase password for the restricted user config.configmap.cnCouchbaseUser that is often used inside the services. The password must contain one digit, one uppercase letter, one lower case letter and one symbol cnCouchbasePassword : P@ssw0rd # -- The Couchbase super user (admin) username. This user is used during initialization only. cnCouchbaseSuperUser : admin # -- Couchbase password for the superuser config.configmap.cnCouchbaseSuperUser that is used during the initialization process. The password must contain one digit, one uppercase letter, one lower case letter and one symbol cnCouchbaseSuperUserPassword : Test1234# # -- Couchbase URL. This should be in FQDN format for either remote or local Couchbase clusters. The address can be an internal address inside the kubernetes cluster cnCouchbaseUrl : cbjanssen.default.svc.cluster.local # -- Couchbase restricted user cnCouchbaseUser : janssen PostgreSQL for persistence storage In a production environment, a production grade PostgreSQL server should be used such as Amazon RDS For testing purposes, you can deploy it on the EKS cluster using the following command: helm install my-release --set auth.postgresPassword=Test1234#,auth.database=gluu -n gluu oci://registry-1.docker.io/bitnamicharts/postgresql Add the following yaml snippet to your override.yaml file: global : cnPersistenceType : sql config : configmap : cnSqlDbName : gluu cnSqlDbPort : 5432 cnSqlDbDialect : pgsql cnSqlDbHost : my-release-postgresql.gluu.svc cnSqlDbUser : postgres cnSqlDbTimezone : UTC cnSqldbUserPassword : Test1234# MySQL for persistence storage In a production environment, a production grade MySQL server should be used such as Amazon RDS For testing purposes, you can deploy it on the EKS cluster using the following command: helm install my-release --set auth.rootPassword=Test1234#,auth.database=gluu -n gluu oci://registry-1.docker.io/bitnamicharts/mysql Add the following yaml snippet to your override.yaml file: global : cnPersistenceType : sql config : configmap : cnSqlDbName : gluu cnSqlDbPort : 3306 cnSqlDbDialect : mysql cnSqlDbHost : my-release-mysql.gluu.svc cnSqlDbUser : root cnSqlDbTimezone : UTC cnSqldbUserPassword : Test1234# So if your desired configuration has FQDN and MySQL, the final override.yaml file will look something like that: global : cnPersistenceType : sql isFqdnRegistered : true fqdn : demoexample.gluu.org #CHANGE-THIS to the FQDN used for Gluu nginx-ingress : ingress : path : / hosts : - demoexample.gluu.org #CHANGE-THIS to the FQDN used for Gluu tls : - secretName : tls-certificate hosts : - demoexample.gluu.org #CHANGE-THIS to the FQDN used for Gluu config : configmap : lbAddr : http:// #Add LB address from previous command cnSqlDbName : gluu cnSqlDbPort : 3306 cnSqlDbDialect : mysql cnSqlDbHost : my-release-mysql.gluu.svc cnSqlDbUser : root cnSqlDbTimezone : UTC cnSqldbUserPassword : Test1234# Install Gluu Flex After finishing all the tweaks to the override.yaml file, we can use it to install gluu flex. helm repo add gluu-flex https://docs.gluu.org/charts helm repo update helm install gluu gluu-flex/gluu -n gluu -f override.yaml Configure Gluu Flex # You can use the Janssen TUI to configure Flex components. The TUI calls the Config API to perform ad hoc configuration.","title":"Amazon EKS"},{"location":"install/helm-install/amazon-eks/#install-gluu-flex-on-eks","text":"","title":"Install Gluu Flex on EKS"},{"location":"install/helm-install/amazon-eks/#system-requirements","text":"The resources may be set minimally to the below: 8-13 GB RAM based on the services deployed 8-11 CPU cores based on the services deployed 50GB hard-disk Use the listing below for a detailed estimation of the minimum required resources. The table contains the default resources recommendation per service. Depending on the use of each service the resources need may be increase or decrease. Service CPU Unit RAM Disk Space Processor Type Required Auth server 2.5 2.5GB N/A 64 Bit Yes fido2 0.5 0.5GB N/A 64 Bit No scim 1 1GB N/A 64 Bit No config - job 0.3 0.3GB N/A 64 Bit Yes on fresh installs persistence - job 0.3 0.3GB N/A 64 Bit Yes on fresh installs nginx 1 1GB N/A 64 Bit Yes if ALB/Istio not used auth-key-rotation 0.3 0.3GB N/A 64 Bit No [Strongly recommended] config-api 1 1GB N/A 64 Bit No casa 0.5 0.5GB N/A 64 Bit No admin-ui 2 2GB N/A 64 Bit No link 0.5 1GB N/A 64 Bit No saml 0.5 1GB N/A 64 Bit No Releases of images are in style 1.0.0-beta.0, 1.0.0-0","title":"System Requirements"},{"location":"install/helm-install/amazon-eks/#initial-setup","text":"Before initiating the setup, please obtain an SSA for Flex trial, after which you will issued a JWT. Install aws cli Configure your AWS user account using aws configure command. This makes you able to authenticate before creating the cluster. Note that this user account must have permissions to work with Amazon EKS IAM roles and service linked roles, AWS CloudFormation, and a VPC and related resources Install kubectl Install eksctl Create cluster using eksctl such as the following example: eksctl create cluster --name gluu-cluster --nodegroup-name gluu-nodes --node-type NODE_TYPE --nodes 2 --managed --region REGION_CODE You can adjust node-type and nodes number as per your desired cluster size To be able to attach volumes to your pod, you need to install the Amazon EBS CSI driver Install Helm3 Create gluu namespace where our resources will reside kubectl create namespace gluu","title":"Initial Setup"},{"location":"install/helm-install/amazon-eks/#gluu-flex-installation-using-helm","text":"Install Nginx-Ingress , if you are not using Istio ingress helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx helm repo add stable https://charts.helm.sh/stable helm repo update helm install nginx ingress-nginx/ingress-nginx Create a file named override.yaml and add changes as per your desired configuration: FQDN/domain is not registered: Get the Loadbalancer address: kubectl get svc nginx-ingress-nginx-controller --output jsonpath='{.status.loadBalancer.ingress[0].hostname}' Add the following yaml snippet to your override.yaml file: global : isFqdnRegistered : false config : configmap : lbAddr : http:// #Add LB address from previous command FQDN/domain is registered: Add the following yaml snippet to your override.yaml file: global : isFqdnRegistered : true fqdn : demoexample.gluu.org #CHANGE-THIS to the FQDN used for Gluu config : configmap : lbAddr : http:// #Add LB address from previous command nginx : ingress : enabled : true path : / hosts : - demoexample.gluu.org #CHANGE-THIS to the FQDN used for Gluu tls : - secretName : tls-certificate hosts : - demoexample.gluu.org #CHANGE-THIS to the FQDN used for Gluu Couchbase for pesistence storage Add the following yaml snippet to your override.yaml file: global : cnPersistenceType : couchbase config : configmap : # The prefix of couchbase buckets. This helps with separation in between different environments and allows for the same couchbase cluster to be used by different setups of Janssen. cnCouchbaseBucketPrefix : jans # -- Couchbase certificate authority string. This must be encoded using base64. This can also be found in your couchbase UI Security > Root Certificate. In mTLS setups this is not required. cnCouchbaseCrt : SWFtTm90YVNlcnZpY2VBY2NvdW50Q2hhbmdlTWV0b09uZQo= # -- The number of replicas per index created. Please note that the number of index nodes must be one greater than the number of index replicas. That means if your couchbase cluster only has 2 index nodes you cannot place the number of replicas to be higher than 1. cnCouchbaseIndexNumReplica : 0 # -- Couchbase password for the restricted user config.configmap.cnCouchbaseUser that is often used inside the services. The password must contain one digit, one uppercase letter, one lower case letter and one symbol cnCouchbasePassword : P@ssw0rd # -- The Couchbase super user (admin) username. This user is used during initialization only. cnCouchbaseSuperUser : admin # -- Couchbase password for the superuser config.configmap.cnCouchbaseSuperUser that is used during the initialization process. The password must contain one digit, one uppercase letter, one lower case letter and one symbol cnCouchbaseSuperUserPassword : Test1234# # -- Couchbase URL. This should be in FQDN format for either remote or local Couchbase clusters. The address can be an internal address inside the kubernetes cluster cnCouchbaseUrl : cbjanssen.default.svc.cluster.local # -- Couchbase restricted user cnCouchbaseUser : janssen PostgreSQL for persistence storage In a production environment, a production grade PostgreSQL server should be used such as Amazon RDS For testing purposes, you can deploy it on the EKS cluster using the following command: helm install my-release --set auth.postgresPassword=Test1234#,auth.database=gluu -n gluu oci://registry-1.docker.io/bitnamicharts/postgresql Add the following yaml snippet to your override.yaml file: global : cnPersistenceType : sql config : configmap : cnSqlDbName : gluu cnSqlDbPort : 5432 cnSqlDbDialect : pgsql cnSqlDbHost : my-release-postgresql.gluu.svc cnSqlDbUser : postgres cnSqlDbTimezone : UTC cnSqldbUserPassword : Test1234# MySQL for persistence storage In a production environment, a production grade MySQL server should be used such as Amazon RDS For testing purposes, you can deploy it on the EKS cluster using the following command: helm install my-release --set auth.rootPassword=Test1234#,auth.database=gluu -n gluu oci://registry-1.docker.io/bitnamicharts/mysql Add the following yaml snippet to your override.yaml file: global : cnPersistenceType : sql config : configmap : cnSqlDbName : gluu cnSqlDbPort : 3306 cnSqlDbDialect : mysql cnSqlDbHost : my-release-mysql.gluu.svc cnSqlDbUser : root cnSqlDbTimezone : UTC cnSqldbUserPassword : Test1234# So if your desired configuration has FQDN and MySQL, the final override.yaml file will look something like that: global : cnPersistenceType : sql isFqdnRegistered : true fqdn : demoexample.gluu.org #CHANGE-THIS to the FQDN used for Gluu nginx-ingress : ingress : path : / hosts : - demoexample.gluu.org #CHANGE-THIS to the FQDN used for Gluu tls : - secretName : tls-certificate hosts : - demoexample.gluu.org #CHANGE-THIS to the FQDN used for Gluu config : configmap : lbAddr : http:// #Add LB address from previous command cnSqlDbName : gluu cnSqlDbPort : 3306 cnSqlDbDialect : mysql cnSqlDbHost : my-release-mysql.gluu.svc cnSqlDbUser : root cnSqlDbTimezone : UTC cnSqldbUserPassword : Test1234# Install Gluu Flex After finishing all the tweaks to the override.yaml file, we can use it to install gluu flex. helm repo add gluu-flex https://docs.gluu.org/charts helm repo update helm install gluu gluu-flex/gluu -n gluu -f override.yaml","title":"Gluu Flex Installation using Helm"},{"location":"install/helm-install/amazon-eks/#configure-gluu-flex","text":"You can use the Janssen TUI to configure Flex components. The TUI calls the Config API to perform ad hoc configuration.","title":"Configure Gluu Flex"},{"location":"install/helm-install/google-gke/","tags":["administration","installation","helm","GKE","Google Cloud","GCP"],"text":"Install Gluu Flex on GKE # System Requirements # The resources may be set minimally to the below: 8-13 GB RAM based on the services deployed 8-11 CPU cores based on the services deployed 50GB hard-disk Use the listing below for a detailed estimation of the minimum required resources. The table contains the default resources recommendation per service. Depending on the use of each service the resources need may be increase or decrease. Service CPU Unit RAM Disk Space Processor Type Required Auth server 2.5 2.5GB N/A 64 Bit Yes fido2 0.5 0.5GB N/A 64 Bit No scim 1 1GB N/A 64 Bit No config - job 0.3 0.3GB N/A 64 Bit Yes on fresh installs persistence - job 0.3 0.3GB N/A 64 Bit Yes on fresh installs nginx 1 1GB N/A 64 Bit Yes if ALB/Istio not used auth-key-rotation 0.3 0.3GB N/A 64 Bit No [Strongly recommended] config-api 1 1GB N/A 64 Bit No casa 0.5 0.5GB N/A 64 Bit No admin-ui 2 2GB N/A 64 Bit No link 0.5 1GB N/A 64 Bit No saml 0.5 1GB N/A 64 Bit No Releases of images are in style 1.0.0-beta.0, 1.0.0-0 Initial Setup # Before initiating the setup, please obtain an SSA for Flex trial, after which you will issued a JWT. Enable GKE API if not enabled yet. If you are using Cloud Shell , you can skip to step 7. Install gcloud . Install kubectl using gcloud components install kubectl command. Install Helm3 . Create cluster using a command such as the following example: gcloud container clusters create gluu-cluster --num-nodes 2 --machine-type e2-standard-4 --zone us-west1-a You can adjust num-nodes and machine-type as per your desired cluster size Create gluu namespace where our resources will reside kubectl create namespace gluu Gluu Flex Installation using Helm # Install Nginx-Ingress , if you are not using Istio ingress helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx helm repo add stable https://charts.helm.sh/stable helm repo update helm install nginx ingress-nginx/ingress-nginx Create a file named override.yaml and add changes as per your desired configuration: FQDN/domain is not registered: Get the Loadbalancer IP: kubectl get svc nginx-ingress-nginx-controller --output jsonpath='{.status.loadBalancer.ingress[0].ip}' Add the following yaml snippet to your override.yaml file: global : lbIp : #Add the Loadbalance IP from the previous command isFqdnRegistered : false FQDN/domain is registered: Add the following yaml snippet to your override.yaml file: global : lbIp : #Add the LoadBalancer IP from the previous command isFqdnRegistered : true fqdn : demoexample.gluu.org #CHANGE-THIS to the FQDN used for Gluu nginx-ingress : ingress : path : / hosts : - demoexample.gluu.org #CHANGE-THIS to the FQDN used for Gluu tls : - secretName : tls-certificate hosts : - demoexample.gluu.org #CHANGE-THIS to the FQDN used for Gluu Couchbase for pesistence storage Add the following yaml snippet to your override.yaml file: global : cnPersistenceType : couchbase config : configmap : # The prefix of couchbase buckets. This helps with separation in between different environments and allows for the same couchbase cluster to be used by different setups of Flex. cnCouchbaseBucketPrefix : jans # -- Couchbase certificate authority string. This must be encoded using base64. This can also be found in your couchbase UI Security > Root Certificate. In mTLS setups this is not required. cnCouchbaseCrt : SWFtTm90YVNlcnZpY2VBY2NvdW50Q2hhbmdlTWV0b09uZQo= # -- The number of replicas per index created. Please note that the number of index nodes must be one greater than the number of index replicas. That means if your couchbase cluster only has 2 index nodes you cannot place the number of replicas to be higher than 1. cnCouchbaseIndexNumReplica : 0 # -- Couchbase password for the restricted user config.configmap.cnCouchbaseUser that is often used inside the services. The password must contain one digit, one uppercase letter, one lower case letter and one symbol cnCouchbasePassword : P@ssw0rd # -- The Couchbase super user (admin) username. This user is used during initialization only. cnCouchbaseSuperUser : admin # -- Couchbase password for the superuser config.configmap.cnCouchbaseSuperUser that is used during the initialization process. The password must contain one digit, one uppercase letter, one lower case letter and one symbol cnCouchbaseSuperUserPassword : Test1234# # -- Couchbase URL. This should be in FQDN format for either remote or local Couchbase clusters. The address can be an internal address inside the kubernetes cluster cnCouchbaseUrl : cbjanssen.default.svc.cluster.local # -- Couchbase restricted user cnCouchbaseUser : janssen PostgreSQL for persistence storage In a production environment, a production grade PostgreSQL server should be used such as Cloud SQL For testing purposes, you can deploy it on the GKE cluster using the following command: helm install my-release --set auth.postgresPassword=Test1234#,auth.database=gluu -n gluu oci://registry-1.docker.io/bitnamicharts/postgresql Add the following yaml snippet to your override.yaml file: global : cnPersistenceType : sql config : configmap : cnSqlDbName : gluu cnSqlDbPort : 5432 cnSqlDbDialect : pgsql cnSqlDbHost : my-release-postgresql.gluu.svc cnSqlDbUser : postgres cnSqlDbTimezone : UTC cnSqldbUserPassword : Test1234# MySQL for persistence storage In a production environment, a production grade MySQL server should be used such as Cloud SQL For testing purposes, you can deploy it on the GKE cluster using the following command: helm install my-release --set auth.rootPassword=Test1234#,auth.database=gluu -n gluu oci://registry-1.docker.io/bitnamicharts/mysql Add the following yaml snippet to your override.yaml file: global : cnPersistenceType : sql config : configmap : cnSqlDbName : gluu cnSqlDbPort : 3306 cnSqlDbDialect : mysql cnSqlDbHost : my-release-mysql.gluu.svc cnSqlDbUser : root cnSqlDbTimezone : UTC cnSqldbUserPassword : Test1234# So if your desired configuration has FQDN and MySQL, the final override.yaml file will look something like that: global : cnPersistenceType : sql lbIp : \"\" #Add the LoadBalancer IP from previous command isFqdnRegistered : true fqdn : demoexample.gluu.org #CHANGE-THIS to the FQDN used for Gluu nginx-ingress : ingress : path : / hosts : - demoexample.gluu.org #CHANGE-THIS to the FQDN used for Gluu tls : - secretName : tls-certificate hosts : - demoexample.gluu.org #CHANGE-THIS to the FQDN used for Gluu config : configmap : cnSqlDbName : gluu cnSqlDbPort : 3306 cnSqlDbDialect : mysql cnSqlDbHost : my-release-mysql.gluu.svc cnSqlDbUser : root cnSqlDbTimezone : UTC cnSqldbUserPassword : Test1234# Install Gluu Flex After finishing all the tweaks to the override.yaml file, we can use it to install gluu flex. helm repo add gluu-flex https://docs.gluu.org/charts helm repo update helm install gluu gluu-flex/gluu -n gluu -f override.yaml Configure Gluu Flex # You can use the Janssen TUI to configure Flex components. The TUI calls the Config API to perform ad hoc configuration.","title":"Google GKE"},{"location":"install/helm-install/google-gke/#install-gluu-flex-on-gke","text":"","title":"Install Gluu Flex on GKE"},{"location":"install/helm-install/google-gke/#system-requirements","text":"The resources may be set minimally to the below: 8-13 GB RAM based on the services deployed 8-11 CPU cores based on the services deployed 50GB hard-disk Use the listing below for a detailed estimation of the minimum required resources. The table contains the default resources recommendation per service. Depending on the use of each service the resources need may be increase or decrease. Service CPU Unit RAM Disk Space Processor Type Required Auth server 2.5 2.5GB N/A 64 Bit Yes fido2 0.5 0.5GB N/A 64 Bit No scim 1 1GB N/A 64 Bit No config - job 0.3 0.3GB N/A 64 Bit Yes on fresh installs persistence - job 0.3 0.3GB N/A 64 Bit Yes on fresh installs nginx 1 1GB N/A 64 Bit Yes if ALB/Istio not used auth-key-rotation 0.3 0.3GB N/A 64 Bit No [Strongly recommended] config-api 1 1GB N/A 64 Bit No casa 0.5 0.5GB N/A 64 Bit No admin-ui 2 2GB N/A 64 Bit No link 0.5 1GB N/A 64 Bit No saml 0.5 1GB N/A 64 Bit No Releases of images are in style 1.0.0-beta.0, 1.0.0-0","title":"System Requirements"},{"location":"install/helm-install/google-gke/#initial-setup","text":"Before initiating the setup, please obtain an SSA for Flex trial, after which you will issued a JWT. Enable GKE API if not enabled yet. If you are using Cloud Shell , you can skip to step 7. Install gcloud . Install kubectl using gcloud components install kubectl command. Install Helm3 . Create cluster using a command such as the following example: gcloud container clusters create gluu-cluster --num-nodes 2 --machine-type e2-standard-4 --zone us-west1-a You can adjust num-nodes and machine-type as per your desired cluster size Create gluu namespace where our resources will reside kubectl create namespace gluu","title":"Initial Setup"},{"location":"install/helm-install/google-gke/#gluu-flex-installation-using-helm","text":"Install Nginx-Ingress , if you are not using Istio ingress helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx helm repo add stable https://charts.helm.sh/stable helm repo update helm install nginx ingress-nginx/ingress-nginx Create a file named override.yaml and add changes as per your desired configuration: FQDN/domain is not registered: Get the Loadbalancer IP: kubectl get svc nginx-ingress-nginx-controller --output jsonpath='{.status.loadBalancer.ingress[0].ip}' Add the following yaml snippet to your override.yaml file: global : lbIp : #Add the Loadbalance IP from the previous command isFqdnRegistered : false FQDN/domain is registered: Add the following yaml snippet to your override.yaml file: global : lbIp : #Add the LoadBalancer IP from the previous command isFqdnRegistered : true fqdn : demoexample.gluu.org #CHANGE-THIS to the FQDN used for Gluu nginx-ingress : ingress : path : / hosts : - demoexample.gluu.org #CHANGE-THIS to the FQDN used for Gluu tls : - secretName : tls-certificate hosts : - demoexample.gluu.org #CHANGE-THIS to the FQDN used for Gluu Couchbase for pesistence storage Add the following yaml snippet to your override.yaml file: global : cnPersistenceType : couchbase config : configmap : # The prefix of couchbase buckets. This helps with separation in between different environments and allows for the same couchbase cluster to be used by different setups of Flex. cnCouchbaseBucketPrefix : jans # -- Couchbase certificate authority string. This must be encoded using base64. This can also be found in your couchbase UI Security > Root Certificate. In mTLS setups this is not required. cnCouchbaseCrt : SWFtTm90YVNlcnZpY2VBY2NvdW50Q2hhbmdlTWV0b09uZQo= # -- The number of replicas per index created. Please note that the number of index nodes must be one greater than the number of index replicas. That means if your couchbase cluster only has 2 index nodes you cannot place the number of replicas to be higher than 1. cnCouchbaseIndexNumReplica : 0 # -- Couchbase password for the restricted user config.configmap.cnCouchbaseUser that is often used inside the services. The password must contain one digit, one uppercase letter, one lower case letter and one symbol cnCouchbasePassword : P@ssw0rd # -- The Couchbase super user (admin) username. This user is used during initialization only. cnCouchbaseSuperUser : admin # -- Couchbase password for the superuser config.configmap.cnCouchbaseSuperUser that is used during the initialization process. The password must contain one digit, one uppercase letter, one lower case letter and one symbol cnCouchbaseSuperUserPassword : Test1234# # -- Couchbase URL. This should be in FQDN format for either remote or local Couchbase clusters. The address can be an internal address inside the kubernetes cluster cnCouchbaseUrl : cbjanssen.default.svc.cluster.local # -- Couchbase restricted user cnCouchbaseUser : janssen PostgreSQL for persistence storage In a production environment, a production grade PostgreSQL server should be used such as Cloud SQL For testing purposes, you can deploy it on the GKE cluster using the following command: helm install my-release --set auth.postgresPassword=Test1234#,auth.database=gluu -n gluu oci://registry-1.docker.io/bitnamicharts/postgresql Add the following yaml snippet to your override.yaml file: global : cnPersistenceType : sql config : configmap : cnSqlDbName : gluu cnSqlDbPort : 5432 cnSqlDbDialect : pgsql cnSqlDbHost : my-release-postgresql.gluu.svc cnSqlDbUser : postgres cnSqlDbTimezone : UTC cnSqldbUserPassword : Test1234# MySQL for persistence storage In a production environment, a production grade MySQL server should be used such as Cloud SQL For testing purposes, you can deploy it on the GKE cluster using the following command: helm install my-release --set auth.rootPassword=Test1234#,auth.database=gluu -n gluu oci://registry-1.docker.io/bitnamicharts/mysql Add the following yaml snippet to your override.yaml file: global : cnPersistenceType : sql config : configmap : cnSqlDbName : gluu cnSqlDbPort : 3306 cnSqlDbDialect : mysql cnSqlDbHost : my-release-mysql.gluu.svc cnSqlDbUser : root cnSqlDbTimezone : UTC cnSqldbUserPassword : Test1234# So if your desired configuration has FQDN and MySQL, the final override.yaml file will look something like that: global : cnPersistenceType : sql lbIp : \"\" #Add the LoadBalancer IP from previous command isFqdnRegistered : true fqdn : demoexample.gluu.org #CHANGE-THIS to the FQDN used for Gluu nginx-ingress : ingress : path : / hosts : - demoexample.gluu.org #CHANGE-THIS to the FQDN used for Gluu tls : - secretName : tls-certificate hosts : - demoexample.gluu.org #CHANGE-THIS to the FQDN used for Gluu config : configmap : cnSqlDbName : gluu cnSqlDbPort : 3306 cnSqlDbDialect : mysql cnSqlDbHost : my-release-mysql.gluu.svc cnSqlDbUser : root cnSqlDbTimezone : UTC cnSqldbUserPassword : Test1234# Install Gluu Flex After finishing all the tweaks to the override.yaml file, we can use it to install gluu flex. helm repo add gluu-flex https://docs.gluu.org/charts helm repo update helm install gluu gluu-flex/gluu -n gluu -f override.yaml","title":"Gluu Flex Installation using Helm"},{"location":"install/helm-install/google-gke/#configure-gluu-flex","text":"You can use the Janssen TUI to configure Flex components. The TUI calls the Config API to perform ad hoc configuration.","title":"Configure Gluu Flex"},{"location":"install/helm-install/local/","tags":["administration","installation","helm"],"text":"Install Gluu Server Locally with minikube and MicroK8s # System Requirements # For local deployments like minikube and MicroK8s or cloud installations in demo mode, resources may be set to the minimum as below: 8 GB RAM 4 CPU cores 50 GB hard-disk Use the listing below for detailed estimation of minimum required resources. Table contains the default resources recommendations per service. Depending on the use of each service the resources needs may increase or decrease. Service CPU Unit RAM Disk Space Processor Type Required Auth server 2.5 2.5GB N/A 64 Bit Yes fido2 0.5 0.5GB N/A 64 Bit No scim 1 1GB N/A 64 Bit No config - job 0.3 0.3GB N/A 64 Bit Yes on fresh installs persistence - job 0.3 0.3GB N/A 64 Bit Yes on fresh installs nginx 1 1GB N/A 64 Bit Yes ALB/Istio not used auth-key-rotation 0.3 0.3GB N/A 64 Bit No [Strongly recommended] config-api 1 1GB N/A 64 Bit No casa 0.5 0.5GB N/A 64 Bit No admin-ui 2 2GB N/A 64 Bit No link 0.5 1GB N/A 64 Bit No saml 0.5 1GB N/A 64 Bit No Releases of images are in style 1.0.0-beta.0, 1.0.0-0 Installation Steps # Before initiating the setup, please obtain an SSA for Flex trial, after which you will issued a JWT. Start a fresh Ubuntu 18.04 / 20.04 / 22.04 VM with ports 443 and 80 open. Then execute the following: sudo su - wget https://raw.githubusercontent.com/GluuFederation/flex/v5.1.6.nightly/automation/startflexdemo.sh && chmod u+x startflexdemo.sh && ./startflexdemo.sh This will install Docker, Microk8s, Helm and Gluu with the default settings that can be found inside values.yaml . The installer will automatically add a record to your hosts record in the VM but if you want to access the endpoints outside the VM you must map the ip of the instance running Ubuntu to the FQDN you provided and then access the endpoints at your browser such in the example in the table below. Service Example endpoint Auth server https://FQDN/.well-known/openid-configuration fido2 https://FQDN/.well-known/fido2-configuration scim https://FQDN/.well-known/scim-configuration Casa https://FQDN/jans-casa Admin-UI https://FQDN/admin Configure Gluu Flex # You can use the Janssen TUI to configure Flex components. The TUI calls the Config API to perform ad hoc configuration.","title":"Local Kubernetes Cluster"},{"location":"install/helm-install/local/#install-gluu-server-locally-with-minikube-and-microk8s","text":"","title":"Install Gluu Server Locally with minikube and MicroK8s"},{"location":"install/helm-install/local/#system-requirements","text":"For local deployments like minikube and MicroK8s or cloud installations in demo mode, resources may be set to the minimum as below: 8 GB RAM 4 CPU cores 50 GB hard-disk Use the listing below for detailed estimation of minimum required resources. Table contains the default resources recommendations per service. Depending on the use of each service the resources needs may increase or decrease. Service CPU Unit RAM Disk Space Processor Type Required Auth server 2.5 2.5GB N/A 64 Bit Yes fido2 0.5 0.5GB N/A 64 Bit No scim 1 1GB N/A 64 Bit No config - job 0.3 0.3GB N/A 64 Bit Yes on fresh installs persistence - job 0.3 0.3GB N/A 64 Bit Yes on fresh installs nginx 1 1GB N/A 64 Bit Yes ALB/Istio not used auth-key-rotation 0.3 0.3GB N/A 64 Bit No [Strongly recommended] config-api 1 1GB N/A 64 Bit No casa 0.5 0.5GB N/A 64 Bit No admin-ui 2 2GB N/A 64 Bit No link 0.5 1GB N/A 64 Bit No saml 0.5 1GB N/A 64 Bit No Releases of images are in style 1.0.0-beta.0, 1.0.0-0","title":"System Requirements"},{"location":"install/helm-install/local/#installation-steps","text":"Before initiating the setup, please obtain an SSA for Flex trial, after which you will issued a JWT. Start a fresh Ubuntu 18.04 / 20.04 / 22.04 VM with ports 443 and 80 open. Then execute the following: sudo su - wget https://raw.githubusercontent.com/GluuFederation/flex/v5.1.6.nightly/automation/startflexdemo.sh && chmod u+x startflexdemo.sh && ./startflexdemo.sh This will install Docker, Microk8s, Helm and Gluu with the default settings that can be found inside values.yaml . The installer will automatically add a record to your hosts record in the VM but if you want to access the endpoints outside the VM you must map the ip of the instance running Ubuntu to the FQDN you provided and then access the endpoints at your browser such in the example in the table below. Service Example endpoint Auth server https://FQDN/.well-known/openid-configuration fido2 https://FQDN/.well-known/fido2-configuration scim https://FQDN/.well-known/scim-configuration Casa https://FQDN/jans-casa Admin-UI https://FQDN/admin","title":"Installation Steps"},{"location":"install/helm-install/local/#configure-gluu-flex","text":"You can use the Janssen TUI to configure Flex components. The TUI calls the Config API to perform ad hoc configuration.","title":"Configure Gluu Flex"},{"location":"install/helm-install/microsoft-azure/","tags":["administration","installation","helm","AKS","Microsoft","Azure"],"text":"Install Gluu Flex on AKS # System Requirements # The resources may be set minimally to the below: 8-13 GB RAM based on the services deployed 8-11 CPU cores based on the services deployed 50GB hard-disk Use the listing below for a detailed estimation of the minimum required resources. The table contains the default resources recommendation per service. Depending on the use of each service the resources need may be increase or decrease. Service CPU Unit RAM Disk Space Processor Type Required Auth server 2.5 2.5GB N/A 64 Bit Yes fido2 0.5 0.5GB N/A 64 Bit No scim 1 1GB N/A 64 Bit No config - job 0.3 0.3GB N/A 64 Bit Yes on fresh installs persistence - job 0.3 0.3GB N/A 64 Bit Yes on fresh installs nginx 1 1GB N/A 64 Bit Yes if ALB/Istio not used auth-key-rotation 0.3 0.3GB N/A 64 Bit No [Strongly recommended] config-api 1 1GB N/A 64 Bit No casa 0.5 0.5GB N/A 64 Bit No admin-ui 2 2GB N/A 64 Bit No link 0.5 1GB N/A 64 Bit No saml 0.5 1GB N/A 64 Bit No Releases of images are in style 1.0.0-beta.0, 1.0.0-0 Initial Setup # Before initiating the setup, please obtain an SSA for Flex trial, after which you will issued a JWT. Install Azure CLI Create a Resource Group az group create --name gluu-resource-group --location eastus Create an AKS cluster such as the following example: az aks create -g gluu-resource-group -n gluu-cluster --enable-managed-identity --node-vm-size NODE_TYPE --node-count 2 --enable-addons monitoring --enable-msi-auth-for-monitoring --generate-ssh-keys You can adjust node-count and node-vm-size as per your desired cluster size Connect to the cluster az aks install-cli az aks get-credentials --resource-group gluu-resource-group --name gluu-cluster Install Helm3 Create gluu namespace where our resources will reside kubectl create namespace gluu Gluu Flex Installation using Helm # Install Nginx-Ingress , if you are not using Istio ingress helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx helm repo add stable https://charts.helm.sh/stable helm repo update helm install nginx ingress-nginx/ingress-nginx Create a file named override.yaml and add changes as per your desired configuration: FQDN/domain is not registered: Get the Loadbalancer IP: kubectl get svc nginx-ingress-nginx-controller --output jsonpath='{.status.loadBalancer.ingress[0].ip}' Add the following yaml snippet to your override.yaml file: global : lbIp : #Add the Loadbalance IP from the previous command isFqdnRegistered : false FQDN/domain is registered: Add the following yaml snippet to your override.yaml file: global : lbIp : #Add the LoadBalancer IP from the previous command isFqdnRegistered : true fqdn : demoexample.gluu.org #CHANGE-THIS to the FQDN used for Gluu nginx-ingress : ingress : path : / hosts : - demoexample.gluu.org #CHANGE-THIS to the FQDN used for Gluu tls : - secretName : tls-certificate hosts : - demoexample.gluu.org #CHANGE-THIS to the FQDN used for Gluu Couchbase for pesistence storage Add the following yaml snippet to your override.yaml file: global : cnPersistenceType : couchbase config : configmap : # The prefix of couchbase buckets. This helps with separation in between different environments and allows for the same couchbase cluster to be used by different setups of Janssen. cnCouchbaseBucketPrefix : jans # -- Couchbase certificate authority string. This must be encoded using base64. This can also be found in your couchbase UI Security > Root Certificate. In mTLS setups this is not required. cnCouchbaseCrt : SWFtTm90YVNlcnZpY2VBY2NvdW50Q2hhbmdlTWV0b09uZQo= # -- The number of replicas per index created. Please note that the number of index nodes must be one greater than the number of index replicas. That means if your couchbase cluster only has 2 index nodes you cannot place the number of replicas to be higher than 1. cnCouchbaseIndexNumReplica : 0 # -- Couchbase password for the restricted user config.configmap.cnCouchbaseUser that is often used inside the services. The password must contain one digit, one uppercase letter, one lower case letter and one symbol cnCouchbasePassword : P@ssw0rd # -- The Couchbase super user (admin) username. This user is used during initialization only. cnCouchbaseSuperUser : admin # -- Couchbase password for the superuser config.configmap.cnCouchbaseSuperUser that is used during the initialization process. The password must contain one digit, one uppercase letter, one lower case letter and one symbol cnCouchbaseSuperUserPassword : Test1234# # -- Couchbase URL. This should be in FQDN format for either remote or local Couchbase clusters. The address can be an internal address inside the kubernetes cluster cnCouchbaseUrl : cbjanssen.default.svc.cluster.local # -- Couchbase restricted user cnCouchbaseUser : janssen PostgreSQL for persistence storage In a production environment, a production grade PostgreSQL server should be used such as Azure Database for PostgreSQL For testing purposes, you can deploy it on the AKS cluster using the following command: helm install my-release --set auth.postgresPassword=Test1234#,auth.database=gluu -n gluu oci://registry-1.docker.io/bitnamicharts/postgresql Add the following yaml snippet to your override.yaml file: global : cnPersistenceType : sql config : configmap : cnSqlDbName : gluu cnSqlDbPort : 5432 cnSqlDbDialect : pgsql cnSqlDbHost : my-release-postgresql.gluu.svc cnSqlDbUser : postgres cnSqlDbTimezone : UTC cnSqldbUserPassword : Test1234# MySQL for persistence storage In a production environment, a production grade MySQL server should be used such as Azure Database for MySQL For testing purposes, you can deploy it on the AKS cluster using the following command: helm install my-release --set auth.rootPassword=Test1234#,auth.database=gluu -n gluu oci://registry-1.docker.io/bitnamicharts/mysql Add the following yaml snippet to your override.yaml file: global : cnPersistenceType : sql config : configmap : cnSqlDbName : gluu cnSqlDbPort : 3306 cnSqlDbDialect : mysql cnSqlDbHost : my-release-mysql.gluu.svc cnSqlDbUser : root cnSqlDbTimezone : UTC cnSqldbUserPassword : Test1234# So if your desired configuration has FQDN and MySQL, the final override.yaml file will look something like that: global : cnPersistenceType : sql lbIp : \"\" #Add the LoadBalancer IP from previous command isFqdnRegistered : true fqdn : demoexample.gluu.org #CHANGE-THIS to the FQDN used for Gluu nginx-ingress : ingress : path : / hosts : - demoexample.gluu.org #CHANGE-THIS to the FQDN used for Gluu tls : - secretName : tls-certificate hosts : - demoexample.gluu.org #CHANGE-THIS to the FQDN used for Gluu config : configmap : cnSqlDbName : gluu cnSqlDbPort : 3306 cnSqlDbDialect : mysql cnSqlDbHost : my-release-mysql.gluu.svc cnSqlDbUser : root cnSqlDbTimezone : UTC cnSqldbUserPassword : Test1234# Install Gluu Flex After finishing all the tweaks to the override.yaml file, we can use it to install gluu flex. helm repo add gluu-flex https://docs.gluu.org/charts helm repo update helm install gluu gluu-flex/gluu -n gluu -f override.yaml Configure Gluu Flex # You can use the Janssen TUI to configure Flex components. The TUI calls the Config API to perform ad hoc configuration.","title":"Microsoft Azure AKS"},{"location":"install/helm-install/microsoft-azure/#install-gluu-flex-on-aks","text":"","title":"Install Gluu Flex on AKS"},{"location":"install/helm-install/microsoft-azure/#system-requirements","text":"The resources may be set minimally to the below: 8-13 GB RAM based on the services deployed 8-11 CPU cores based on the services deployed 50GB hard-disk Use the listing below for a detailed estimation of the minimum required resources. The table contains the default resources recommendation per service. Depending on the use of each service the resources need may be increase or decrease. Service CPU Unit RAM Disk Space Processor Type Required Auth server 2.5 2.5GB N/A 64 Bit Yes fido2 0.5 0.5GB N/A 64 Bit No scim 1 1GB N/A 64 Bit No config - job 0.3 0.3GB N/A 64 Bit Yes on fresh installs persistence - job 0.3 0.3GB N/A 64 Bit Yes on fresh installs nginx 1 1GB N/A 64 Bit Yes if ALB/Istio not used auth-key-rotation 0.3 0.3GB N/A 64 Bit No [Strongly recommended] config-api 1 1GB N/A 64 Bit No casa 0.5 0.5GB N/A 64 Bit No admin-ui 2 2GB N/A 64 Bit No link 0.5 1GB N/A 64 Bit No saml 0.5 1GB N/A 64 Bit No Releases of images are in style 1.0.0-beta.0, 1.0.0-0","title":"System Requirements"},{"location":"install/helm-install/microsoft-azure/#initial-setup","text":"Before initiating the setup, please obtain an SSA for Flex trial, after which you will issued a JWT. Install Azure CLI Create a Resource Group az group create --name gluu-resource-group --location eastus Create an AKS cluster such as the following example: az aks create -g gluu-resource-group -n gluu-cluster --enable-managed-identity --node-vm-size NODE_TYPE --node-count 2 --enable-addons monitoring --enable-msi-auth-for-monitoring --generate-ssh-keys You can adjust node-count and node-vm-size as per your desired cluster size Connect to the cluster az aks install-cli az aks get-credentials --resource-group gluu-resource-group --name gluu-cluster Install Helm3 Create gluu namespace where our resources will reside kubectl create namespace gluu","title":"Initial Setup"},{"location":"install/helm-install/microsoft-azure/#gluu-flex-installation-using-helm","text":"Install Nginx-Ingress , if you are not using Istio ingress helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx helm repo add stable https://charts.helm.sh/stable helm repo update helm install nginx ingress-nginx/ingress-nginx Create a file named override.yaml and add changes as per your desired configuration: FQDN/domain is not registered: Get the Loadbalancer IP: kubectl get svc nginx-ingress-nginx-controller --output jsonpath='{.status.loadBalancer.ingress[0].ip}' Add the following yaml snippet to your override.yaml file: global : lbIp : #Add the Loadbalance IP from the previous command isFqdnRegistered : false FQDN/domain is registered: Add the following yaml snippet to your override.yaml file: global : lbIp : #Add the LoadBalancer IP from the previous command isFqdnRegistered : true fqdn : demoexample.gluu.org #CHANGE-THIS to the FQDN used for Gluu nginx-ingress : ingress : path : / hosts : - demoexample.gluu.org #CHANGE-THIS to the FQDN used for Gluu tls : - secretName : tls-certificate hosts : - demoexample.gluu.org #CHANGE-THIS to the FQDN used for Gluu Couchbase for pesistence storage Add the following yaml snippet to your override.yaml file: global : cnPersistenceType : couchbase config : configmap : # The prefix of couchbase buckets. This helps with separation in between different environments and allows for the same couchbase cluster to be used by different setups of Janssen. cnCouchbaseBucketPrefix : jans # -- Couchbase certificate authority string. This must be encoded using base64. This can also be found in your couchbase UI Security > Root Certificate. In mTLS setups this is not required. cnCouchbaseCrt : SWFtTm90YVNlcnZpY2VBY2NvdW50Q2hhbmdlTWV0b09uZQo= # -- The number of replicas per index created. Please note that the number of index nodes must be one greater than the number of index replicas. That means if your couchbase cluster only has 2 index nodes you cannot place the number of replicas to be higher than 1. cnCouchbaseIndexNumReplica : 0 # -- Couchbase password for the restricted user config.configmap.cnCouchbaseUser that is often used inside the services. The password must contain one digit, one uppercase letter, one lower case letter and one symbol cnCouchbasePassword : P@ssw0rd # -- The Couchbase super user (admin) username. This user is used during initialization only. cnCouchbaseSuperUser : admin # -- Couchbase password for the superuser config.configmap.cnCouchbaseSuperUser that is used during the initialization process. The password must contain one digit, one uppercase letter, one lower case letter and one symbol cnCouchbaseSuperUserPassword : Test1234# # -- Couchbase URL. This should be in FQDN format for either remote or local Couchbase clusters. The address can be an internal address inside the kubernetes cluster cnCouchbaseUrl : cbjanssen.default.svc.cluster.local # -- Couchbase restricted user cnCouchbaseUser : janssen PostgreSQL for persistence storage In a production environment, a production grade PostgreSQL server should be used such as Azure Database for PostgreSQL For testing purposes, you can deploy it on the AKS cluster using the following command: helm install my-release --set auth.postgresPassword=Test1234#,auth.database=gluu -n gluu oci://registry-1.docker.io/bitnamicharts/postgresql Add the following yaml snippet to your override.yaml file: global : cnPersistenceType : sql config : configmap : cnSqlDbName : gluu cnSqlDbPort : 5432 cnSqlDbDialect : pgsql cnSqlDbHost : my-release-postgresql.gluu.svc cnSqlDbUser : postgres cnSqlDbTimezone : UTC cnSqldbUserPassword : Test1234# MySQL for persistence storage In a production environment, a production grade MySQL server should be used such as Azure Database for MySQL For testing purposes, you can deploy it on the AKS cluster using the following command: helm install my-release --set auth.rootPassword=Test1234#,auth.database=gluu -n gluu oci://registry-1.docker.io/bitnamicharts/mysql Add the following yaml snippet to your override.yaml file: global : cnPersistenceType : sql config : configmap : cnSqlDbName : gluu cnSqlDbPort : 3306 cnSqlDbDialect : mysql cnSqlDbHost : my-release-mysql.gluu.svc cnSqlDbUser : root cnSqlDbTimezone : UTC cnSqldbUserPassword : Test1234# So if your desired configuration has FQDN and MySQL, the final override.yaml file will look something like that: global : cnPersistenceType : sql lbIp : \"\" #Add the LoadBalancer IP from previous command isFqdnRegistered : true fqdn : demoexample.gluu.org #CHANGE-THIS to the FQDN used for Gluu nginx-ingress : ingress : path : / hosts : - demoexample.gluu.org #CHANGE-THIS to the FQDN used for Gluu tls : - secretName : tls-certificate hosts : - demoexample.gluu.org #CHANGE-THIS to the FQDN used for Gluu config : configmap : cnSqlDbName : gluu cnSqlDbPort : 3306 cnSqlDbDialect : mysql cnSqlDbHost : my-release-mysql.gluu.svc cnSqlDbUser : root cnSqlDbTimezone : UTC cnSqldbUserPassword : Test1234# Install Gluu Flex After finishing all the tweaks to the override.yaml file, we can use it to install gluu flex. helm repo add gluu-flex https://docs.gluu.org/charts helm repo update helm install gluu gluu-flex/gluu -n gluu -f override.yaml","title":"Gluu Flex Installation using Helm"},{"location":"install/helm-install/microsoft-azure/#configure-gluu-flex","text":"You can use the Janssen TUI to configure Flex components. The TUI calls the Config API to perform ad hoc configuration.","title":"Configure Gluu Flex"},{"location":"install/helm-install/rancher/","tags":["administration","installation","helm"],"text":"Install Gluu Server Using Rancher Marketplace # For a more generic Gluu Flex installation on Rancher, you can follow this comprehensive guide. Also, there are multiple Rancher installation options . For this quick start setup we will use a single node Kubernetes install in docker with a self-signed certificate . Installation Steps # Note If you are deploying an Ingress controller on a single node deployment, in which Ingress utilizes ports 80 and 443, then you have to adjust the host ports mapped for the rancher/rancher container. Here's an example on how to do that. Before initiating the setup, please obtain an SSA for Flex trial, after which you will issued a JWT. Provision a Linux 4 CPU, 16 GB RAM, and 50GB SSD VM with ports 443 and 80 open. Save the VM IP address. For development environments, the VM can be set up using VMWare Workstation Player or VirtualBox with Ubuntu 20.04 operating system running on a VM. Install Docker . Execute docker run -d --restart = unless-stopped -p 80 :80 -p 443 :443 --privileged rancher/rancher:latest The final line of the returned text is the container-id , which you'll need for the next step. Execute the following command to get the bootstrap password for login. docker logs 2 > & 1 | grep \"Bootstrap Password:\" Head to https:// and log in with the username admin and the password from the previous step. If you are logging into Rancher for the first time, you'll need to enter just the password, and on the next step, Rancher will ask you to reset your current password. Next, you'll see the Rancher home page with a list of existing clusters. By default, the name of the newly created cluster would be local . Click on the cluster name to go to the dashboard. From the top-left menu expand Apps and click Charts . Search for Gluu and begin your installation. During Step 1 of installation, be sure to select the Customize Helm options before install option. In Step 2, customize the settings for the Gluu installation. Specifically Optional Services from where you can enable Gluu modules. In Step 3, unselect the Wait option and start the installation.","title":"Rancher Marketplace"},{"location":"install/helm-install/rancher/#install-gluu-server-using-rancher-marketplace","text":"For a more generic Gluu Flex installation on Rancher, you can follow this comprehensive guide. Also, there are multiple Rancher installation options . For this quick start setup we will use a single node Kubernetes install in docker with a self-signed certificate .","title":"Install Gluu Server Using Rancher Marketplace"},{"location":"install/helm-install/rancher/#installation-steps","text":"Note If you are deploying an Ingress controller on a single node deployment, in which Ingress utilizes ports 80 and 443, then you have to adjust the host ports mapped for the rancher/rancher container. Here's an example on how to do that. Before initiating the setup, please obtain an SSA for Flex trial, after which you will issued a JWT. Provision a Linux 4 CPU, 16 GB RAM, and 50GB SSD VM with ports 443 and 80 open. Save the VM IP address. For development environments, the VM can be set up using VMWare Workstation Player or VirtualBox with Ubuntu 20.04 operating system running on a VM. Install Docker . Execute docker run -d --restart = unless-stopped -p 80 :80 -p 443 :443 --privileged rancher/rancher:latest The final line of the returned text is the container-id , which you'll need for the next step. Execute the following command to get the bootstrap password for login. docker logs 2 > & 1 | grep \"Bootstrap Password:\" Head to https:// and log in with the username admin and the password from the previous step. If you are logging into Rancher for the first time, you'll need to enter just the password, and on the next step, Rancher will ask you to reset your current password. Next, you'll see the Rancher home page with a list of existing clusters. By default, the name of the newly created cluster would be local . Click on the cluster name to go to the dashboard. From the top-left menu expand Apps and click Charts . Search for Gluu and begin your installation. During Step 1 of installation, be sure to select the Customize Helm options before install option. In Step 2, customize the settings for the Gluu installation. Specifically Optional Services from where you can enable Gluu modules. In Step 3, unselect the Wait option and start the installation.","title":"Installation Steps"},{"location":"install/vm-install/rhel/","tags":["administration","installation","vm","RHEL","CentOS"],"text":"Install Gluu Flex On Red Hat EL # This is a step-by-step guide for installation and uninstallation of Gluu Flex on Ubuntu Linux. Prerequisites # Ensure that the OS platform is one of the supported versions VM should meet VM system requirements Make sure that if SELinux is installed then it is put into permissive mode If the server firewall is running, make sure you allow https , which is needed for OpenID and FIDO. sudo firewall-cmd --permanent --zone = public --add-service = https sudo firewall-cmd --reload ; Install EPEL and mod-auth-openidc as dependencies sudo yum -y install https://dl.fedoraproject.org/pub/epel/epel-release-latest- $( rpm -E %rhel ) .noarch.rpm sudo yum -y module enable mod_auth_openidc ; Please obtain an SSA to trial Flex, after which you are issued a JWT that you can use during installation. SSA should be stored in a text file on an accessible path. Install the Package # Download and Verify the Release Package # Download the release package from the Github Flex Releases wget https://github.com/GluuFederation/flex/releases/download/v5.1.6.nightly/flex-5.1.6.nightly-el8.x86_64.rpm -P /tmp GPG key is used to ensure the authenticity of the downloaded package during the installation process. If the key is not found, the installation step would fail. Use the commands below to download and import the GPG key. wget https://github.com/GluuFederation/flex/files/11814579/automation-flex-public-gpg.zip unzip automation-flex-public-gpg.zip sudo rpm -import automation-flex-public-gpg.asc Verify the integrity of the downloaded package using published sha256sum . Download the sha256sum file for the package wget https://github.com/GluuFederation/flex/releases/download/v5.1.6.nightly/flex-5.1.6.nightly-el8.x86_64.rpm.sha256sum -P /tmp Run the command below from the directory where the downloaded package and the .sha256sum files are located. cd /tmp ; sha256sum -c flex-5.1.6.nightly-el8.x86_64.rpm.sha256sum ; Output similar to below should confirm the integrity of the downloaded package. flex-5.1.6.nightly-el8.x86_64.rpm : ok Install the Release Package # sudo yum install ./flex-5.1.6.nightly-el8.x86_64.rpm Run the setup script # Execute the setup script with command below: sudo python3 /opt/jans/jans-setup/flex/flex-linux-setup/flex_setup.py If Admin-UI component is being installed, then the script will require SSA input, either as text or as a file path. This should be the SSA or file which was acquired as part of prerequisite step . Install Admin UI [Y/n]: y Please enter path of file containing SSA or paste SSA (q to exit): Alternatively, for SSA file can be passed as a parameter to the setup script as below. python3 /opt/jans/jans-setup/flex/flex-linux-setup/flex_setup.py -admin-ui-ssa [ filename ] Verify and Access the Installation # Verify that installation has been successful and all installed components are accessible using the steps below Log in to Text User Interface (TUI) /opt/jans/jans-cli/jans_cli_tui.py Full TUI documentation can be found here Log into Admin-UI using URI below https://FQDN/admin When troubleshooting issues with Admin UI access, it's advisable to check the logs , refer to the FAQ , and review service dependencies for potential solutions. Access Casa using URI below https://FQDN/jans-casa Enabling HTTPS # To enable communication with Janssen Server over TLS (https) in a production environment, Janssen Server needs details about CA certificate. Update the HTTPS cofiguration file https_jans.conf as shown below: Note Want to use Let's Encrypt to get a certificate? Follow this guide . Open https_jans.conf sudo vi /etc/httpd/conf.d/https_jans.conf Update SSLCertificateFile and SSLCertificateKeyFile parameters values SSLCertificateFile location_of_fullchain.pem SSLCertificateKeyFile location_of_privkey.pem Restart httpd service for changes to take effect sudo service httpd restart Uninstallation # Removing Flex is a two step process: Uninstall Gluu Flex Uninstall Janssen Packages If you have not run the setup script, you can skip step 1 and just remove the package. Uninstall Gluu Flex # Use the command below to uninstall the Gluu Flex server sudo python3 /opt/jans/jans-setup/flex/flex-linux-setup/flex_setup.py --remove-flex Output: [ec2-user@manojs1978-lenient-drum ~]$ sudo python3 /opt/jans/jans-setup/flex/flex-linux-setup/flex_setup.py --remove-flex This process is irreversible. Gluu Flex Components will be removed Are you sure to uninstall Gluu Flex? [yes/N] yes Profile was detected as jans. Log Files: /opt/jans/jans-setup/logs/flex-setup.log /opt/jans/jans-setup/logs/flex-setup-error.log /opt/jans/jans-setup/setup_app/pylib/jwt/utils.py:7: CryptographyDeprecationWarning: Python 3.6 is no longer supported by the Python core team. Therefore, support for it is deprecated in cryptography and will be removed in a future release. from cryptography.hazmat.primitives.asymmetric.ec import EllipticCurve Please wait while collecting properties... Uninstalling Gluu Casa - Deleting /etc/default/casa - Deleting /etc/systemd/system/casa.service - Removing casa directives from apache configuration - Deleting /opt/jans/jetty/jans-auth/custom/libs/casa-config.jar - Removing plugin /opt/jans/jetty/jans-auth/custom/libs/casa-config.jar from Jans Auth Configuration - Deleting /opt/jans/python/libs/Casa.py - Deleting /opt/jans/python/libs/casa-external_fido2.py - Deleting /opt/jans/python/libs/casa-external_otp.py - Deleting /opt/jans/python/libs/casa-external_super_gluu.py - Deleting /opt/jans/python/libs/casa-external_twilio_sms.py - Deleting casa client from db backend - Deleting casa client scopes from db backend - Deleting casa configuration from db backend - Deleting script 3000-F75A from db backend - Deleting /opt/jans/jetty/casa Uninstalling Gluu Admin-UI - Deleting Gluu Flex Admin UI Client 2001.931e814d-01e2-4983-898f-91bf93670f7b - Removing Admin UI directives from apache configuration - Deleting /opt/jans/jetty/jans-config-api/custom/libs/gluu-flex-admin-ui-plugin.jar - Removing plugin /opt/jans/jetty/jans-config-api/custom/libs/gluu-flex-admin-ui-plugin.jar from Jans Config API Configuration - Deleting /opt/jans/jetty/jans-config-api/custom/config/log4j2-adminui.xml - Deleting /opt/jans/jetty/jans-config-api/custom/config/log4j2.xml - Rewriting Jans CLI init file for plugins - Deleting /var/www/html/admin Disabling script A51E-76DA Restarting Apache Restarting Jans Auth Restarting Janssen Config Api Uninstall Janssen Packages # The command below removes and uninstall the jans package sudo python3 /opt/jans/jans-setup/install.py -uninstall Output: [ec2-user@manojs1978-lenient-drum ~]$ sudo python3 /opt/jans/jans-setup/install.py -uninstall This process is irreversible. You will lose all data related to Janssen Server. Are you sure to uninstall Janssen Server? [yes/N] yes Uninstalling Jannsen Server... Removing /etc/default/jans-config-api Stopping jans-config-api Removing /etc/default/jans-auth Stopping jans-auth Removing /etc/default/jans-fido2 Stopping jans-fido2 Removing /etc/default/jans-scim Stopping jans-scim Removing /etc/default/jans-cache-refresh Stopping jans-cache-refresh Executing rm -r -f /etc/certs Executing rm -r -f /etc/jans Executing rm -r -f /opt/jans Executing rm -r -f /opt/amazon-corretto* Executing rm -r -f /opt/jre Executing rm -r -f /opt/node* Executing rm -r -f /opt/jetty* Executing rm -r -f /opt/jython* Executing rm -r -f /opt/dist Removing /etc/httpd/conf.d/https_jans.conf Remove Gluu Flex Packages: # List existing Gluu packages with: sudo yum list installed | grep flex Remove packages: sudo yum remove Uninstalling Admin UI # To uninstall the Admin UI from your Flex installation, execute this command: sudo python3 /opt/jans/jans-setup/flex/flex-linux-setup/flex_setup.py --remove-flex Updating Admin UI # To update the Admin UI in an existing Flex installation, execute this command: sudo python3 /opt/jans/jans-setup/flex/flex-linux-setup/flex_setup.py --update-admin-ui","title":"RHEL"},{"location":"install/vm-install/rhel/#install-gluu-flex-on-red-hat-el","text":"This is a step-by-step guide for installation and uninstallation of Gluu Flex on Ubuntu Linux.","title":"Install Gluu Flex On Red Hat EL"},{"location":"install/vm-install/rhel/#prerequisites","text":"Ensure that the OS platform is one of the supported versions VM should meet VM system requirements Make sure that if SELinux is installed then it is put into permissive mode If the server firewall is running, make sure you allow https , which is needed for OpenID and FIDO. sudo firewall-cmd --permanent --zone = public --add-service = https sudo firewall-cmd --reload ; Install EPEL and mod-auth-openidc as dependencies sudo yum -y install https://dl.fedoraproject.org/pub/epel/epel-release-latest- $( rpm -E %rhel ) .noarch.rpm sudo yum -y module enable mod_auth_openidc ; Please obtain an SSA to trial Flex, after which you are issued a JWT that you can use during installation. SSA should be stored in a text file on an accessible path.","title":"Prerequisites"},{"location":"install/vm-install/rhel/#install-the-package","text":"","title":"Install the Package"},{"location":"install/vm-install/rhel/#download-and-verify-the-release-package","text":"Download the release package from the Github Flex Releases wget https://github.com/GluuFederation/flex/releases/download/v5.1.6.nightly/flex-5.1.6.nightly-el8.x86_64.rpm -P /tmp GPG key is used to ensure the authenticity of the downloaded package during the installation process. If the key is not found, the installation step would fail. Use the commands below to download and import the GPG key. wget https://github.com/GluuFederation/flex/files/11814579/automation-flex-public-gpg.zip unzip automation-flex-public-gpg.zip sudo rpm -import automation-flex-public-gpg.asc Verify the integrity of the downloaded package using published sha256sum . Download the sha256sum file for the package wget https://github.com/GluuFederation/flex/releases/download/v5.1.6.nightly/flex-5.1.6.nightly-el8.x86_64.rpm.sha256sum -P /tmp Run the command below from the directory where the downloaded package and the .sha256sum files are located. cd /tmp ; sha256sum -c flex-5.1.6.nightly-el8.x86_64.rpm.sha256sum ; Output similar to below should confirm the integrity of the downloaded package. flex-5.1.6.nightly-el8.x86_64.rpm : ok","title":"Download and Verify the Release Package"},{"location":"install/vm-install/rhel/#install-the-release-package","text":"sudo yum install ./flex-5.1.6.nightly-el8.x86_64.rpm","title":"Install the Release Package"},{"location":"install/vm-install/rhel/#run-the-setup-script","text":"Execute the setup script with command below: sudo python3 /opt/jans/jans-setup/flex/flex-linux-setup/flex_setup.py If Admin-UI component is being installed, then the script will require SSA input, either as text or as a file path. This should be the SSA or file which was acquired as part of prerequisite step . Install Admin UI [Y/n]: y Please enter path of file containing SSA or paste SSA (q to exit): Alternatively, for SSA file can be passed as a parameter to the setup script as below. python3 /opt/jans/jans-setup/flex/flex-linux-setup/flex_setup.py -admin-ui-ssa [ filename ]","title":"Run the setup script"},{"location":"install/vm-install/rhel/#verify-and-access-the-installation","text":"Verify that installation has been successful and all installed components are accessible using the steps below Log in to Text User Interface (TUI) /opt/jans/jans-cli/jans_cli_tui.py Full TUI documentation can be found here Log into Admin-UI using URI below https://FQDN/admin When troubleshooting issues with Admin UI access, it's advisable to check the logs , refer to the FAQ , and review service dependencies for potential solutions. Access Casa using URI below https://FQDN/jans-casa","title":"Verify and Access the Installation"},{"location":"install/vm-install/rhel/#enabling-https","text":"To enable communication with Janssen Server over TLS (https) in a production environment, Janssen Server needs details about CA certificate. Update the HTTPS cofiguration file https_jans.conf as shown below: Note Want to use Let's Encrypt to get a certificate? Follow this guide . Open https_jans.conf sudo vi /etc/httpd/conf.d/https_jans.conf Update SSLCertificateFile and SSLCertificateKeyFile parameters values SSLCertificateFile location_of_fullchain.pem SSLCertificateKeyFile location_of_privkey.pem Restart httpd service for changes to take effect sudo service httpd restart","title":"Enabling HTTPS"},{"location":"install/vm-install/rhel/#uninstallation","text":"Removing Flex is a two step process: Uninstall Gluu Flex Uninstall Janssen Packages If you have not run the setup script, you can skip step 1 and just remove the package.","title":"Uninstallation"},{"location":"install/vm-install/rhel/#uninstall-gluu-flex","text":"Use the command below to uninstall the Gluu Flex server sudo python3 /opt/jans/jans-setup/flex/flex-linux-setup/flex_setup.py --remove-flex Output: [ec2-user@manojs1978-lenient-drum ~]$ sudo python3 /opt/jans/jans-setup/flex/flex-linux-setup/flex_setup.py --remove-flex This process is irreversible. Gluu Flex Components will be removed Are you sure to uninstall Gluu Flex? [yes/N] yes Profile was detected as jans. Log Files: /opt/jans/jans-setup/logs/flex-setup.log /opt/jans/jans-setup/logs/flex-setup-error.log /opt/jans/jans-setup/setup_app/pylib/jwt/utils.py:7: CryptographyDeprecationWarning: Python 3.6 is no longer supported by the Python core team. Therefore, support for it is deprecated in cryptography and will be removed in a future release. from cryptography.hazmat.primitives.asymmetric.ec import EllipticCurve Please wait while collecting properties... Uninstalling Gluu Casa - Deleting /etc/default/casa - Deleting /etc/systemd/system/casa.service - Removing casa directives from apache configuration - Deleting /opt/jans/jetty/jans-auth/custom/libs/casa-config.jar - Removing plugin /opt/jans/jetty/jans-auth/custom/libs/casa-config.jar from Jans Auth Configuration - Deleting /opt/jans/python/libs/Casa.py - Deleting /opt/jans/python/libs/casa-external_fido2.py - Deleting /opt/jans/python/libs/casa-external_otp.py - Deleting /opt/jans/python/libs/casa-external_super_gluu.py - Deleting /opt/jans/python/libs/casa-external_twilio_sms.py - Deleting casa client from db backend - Deleting casa client scopes from db backend - Deleting casa configuration from db backend - Deleting script 3000-F75A from db backend - Deleting /opt/jans/jetty/casa Uninstalling Gluu Admin-UI - Deleting Gluu Flex Admin UI Client 2001.931e814d-01e2-4983-898f-91bf93670f7b - Removing Admin UI directives from apache configuration - Deleting /opt/jans/jetty/jans-config-api/custom/libs/gluu-flex-admin-ui-plugin.jar - Removing plugin /opt/jans/jetty/jans-config-api/custom/libs/gluu-flex-admin-ui-plugin.jar from Jans Config API Configuration - Deleting /opt/jans/jetty/jans-config-api/custom/config/log4j2-adminui.xml - Deleting /opt/jans/jetty/jans-config-api/custom/config/log4j2.xml - Rewriting Jans CLI init file for plugins - Deleting /var/www/html/admin Disabling script A51E-76DA Restarting Apache Restarting Jans Auth Restarting Janssen Config Api","title":"Uninstall Gluu Flex"},{"location":"install/vm-install/rhel/#uninstall-janssen-packages","text":"The command below removes and uninstall the jans package sudo python3 /opt/jans/jans-setup/install.py -uninstall Output: [ec2-user@manojs1978-lenient-drum ~]$ sudo python3 /opt/jans/jans-setup/install.py -uninstall This process is irreversible. You will lose all data related to Janssen Server. Are you sure to uninstall Janssen Server? [yes/N] yes Uninstalling Jannsen Server... Removing /etc/default/jans-config-api Stopping jans-config-api Removing /etc/default/jans-auth Stopping jans-auth Removing /etc/default/jans-fido2 Stopping jans-fido2 Removing /etc/default/jans-scim Stopping jans-scim Removing /etc/default/jans-cache-refresh Stopping jans-cache-refresh Executing rm -r -f /etc/certs Executing rm -r -f /etc/jans Executing rm -r -f /opt/jans Executing rm -r -f /opt/amazon-corretto* Executing rm -r -f /opt/jre Executing rm -r -f /opt/node* Executing rm -r -f /opt/jetty* Executing rm -r -f /opt/jython* Executing rm -r -f /opt/dist Removing /etc/httpd/conf.d/https_jans.conf","title":"Uninstall Janssen Packages"},{"location":"install/vm-install/rhel/#remove-gluu-flex-packages","text":"List existing Gluu packages with: sudo yum list installed | grep flex Remove packages: sudo yum remove ","title":"Remove Gluu Flex Packages:"},{"location":"install/vm-install/rhel/#uninstalling-admin-ui","text":"To uninstall the Admin UI from your Flex installation, execute this command: sudo python3 /opt/jans/jans-setup/flex/flex-linux-setup/flex_setup.py --remove-flex","title":"Uninstalling Admin UI"},{"location":"install/vm-install/rhel/#updating-admin-ui","text":"To update the Admin UI in an existing Flex installation, execute this command: sudo python3 /opt/jans/jans-setup/flex/flex-linux-setup/flex_setup.py --update-admin-ui","title":"Updating Admin UI"},{"location":"install/vm-install/suse/","tags":["administration","installation","vm","SUSE","SLES","Tumbleweed"],"text":"Install Gluu Flex On SUSE Linux # This is a step-by-step guide for installation and uninstallation of Gluu Flex on SUSE Linux distributions Prerequisites # Ensure that the OS platform is one of the supported versions VM should meet VM system requirements Make sure that if SELinux is installed then it is put into permissive mode If the server firewall is running, make sure you allow https , which is needed for OpenID and FIDO. sudo firewall-cmd --permanent --zone = public --add-service = https sudo firewall-cmd --reload for SUSE Linux Enterprise(SLES) we need to enable PackageHub as per OS version and architecture sudo SUSEConnect -p PackageHub/15.4/x86_64 Please obtain an SSA to trial Flex, after which you are issued a JWT that you can use during installation. SSA should be stored in a text file on an accessible path. Install the Package # Download and Verify the Release Package # Download the release package from the GitHub FLEX Releases wget https://github.com/GluuFederation/flex/releases/download/v5.1.6.nightly/flex-5.1.6.nightly-suse15.x86_64.rpm -P ~/ GPG key is used to ensure the authenticity of the downloaded package during the installation process. If the key is not found, the installation step would fail. Use the commands below to download and import the GPG key. wget https://github.com/GluuFederation/flex/files/11814579/automation-flex-public-gpg.zip unzip automation-flex-public-gpg.zip sudo rpm -import automation-flex-public-gpg.asc Verify the integrity of the downloaded package using published sha256sum . Download the sha256sum file for the package wget https://github.com/GluuFederation/flex/releases/download/v5.1.6.nightly/flex-5.1.6.nightly-suse15.x86_64.rpm.sha256sum -P ~/ Verify package integrity sha256sum -c flex-5.1.6.nightly-suse15.x86_64.rpm.sha256sum You should see: flex-5.1.6.nightly-suse15.x86_64.rpm: ok Install the Release Package # Use SUSE zypper to install sudo zypper install ~/flex-5.1.6.nightly-suse15.x86_64.rpm Run the setup script # Run the setup script: Execute the setup script with command below: sudo python3 /opt/jans/jans-setup/flex/flex-linux-setup/flex_setup.py If Admin-UI component is being installed, then the script will require SSA input, either as text or as a file path. This should be the SSA or file which was acquired as part of prerequisite step . Install Admin UI [Y/n]: y Please enter path of file containing SSA or paste SSA (q to exit): Alternatively, for SSA file can be passed as a parameter to the setup script as below. sudo python3 /opt/jans/jans-setup/flex/flex-linux-setup/flex_setup.py -admin-ui-ssa [ filename ] Verify and Access the Installation # Verify that installation has been successful and all installed components are accessible using the steps below: Log in to Text User Interface (TUI) /opt/jans/jans-cli/jans_cli_tui.py TUI is a text-based configuration tool for Gluu Flex Server. Log into Admin-UI using URI below https://FQDN/admin When troubleshooting issues with Admin UI access, it's advisable to check the logs , refer to the FAQ , and review service dependencies for potential solutions. Access Casa using URI below https://FQDN/jans-casa Enabling HTTPS # To enable communication with Janssen Server over TLS (https) in a production environment, Janssen Server needs details about CA certificate. Update the HTTPS cofiguration file https_jans.conf as shown below: Note Want to use Let's Encrypt to get a certificate? Follow this guide . Open _https_jans.conf sudo vi /etc/apache2/vhosts.d/_https_jans.conf ``` - Update ` SSLCertificateFile ` and ` SSLCertificateKeyFile ` parameters values ``` bash SSLCertificateFile location_of_fullchain.pem SSLCertificateKeyFile location_of_privkey.pem Restart apache service for changes to take effect sudo /usr/sbin/rcapache2 restart Uninstallation # Removing Flex is a two step process: Uninstall Gluu Flex and Uninstall Janssen Packages Remove Gluu Packages If you have not run the setup script, you can skip step 1 and just remove the package. First use the command below to uninstall the Gluu Flex server sudo python3 /opt/jans/jans-setup/flex/flex-linux-setup/flex_setup.py --remove-flex the output will be like this: sudo python3 /opt/jans/jans-setup/flex/flex-linux-setup/flex_setup.py --remove-flex This process is irreversible. Gluu Flex Components will be removed Are you sure to uninstall Gluu Flex? [yes/N] yes Profile was detected as jans. Log Files: /opt/jans/jans-setup/logs/flex-setup.log /opt/jans/jans-setup/logs/flex-setup-error.log /opt/jans/jans-setup/setup_app/pylib/jwt/utils.py:7: CryptographyDeprecationWarning: Python 3.6 is no longer supported by the Python core team. Therefore, support for it is deprecated in cryptography and will be removed in a future release. from cryptography.hazmat.primitives.asymmetric.ec import EllipticCurve Please wait while collecting properties... Uninstalling Gluu Casa - Deleting /etc/default/casa - Deleting /etc/systemd/system/casa.service - Removing casa directives from apache configuration - Deleting /opt/jans/jetty/jans-auth/custom/libs/casa-config.jar - Removing plugin /opt/jans/jetty/jans-auth/custom/libs/casa-config.jar from Jans Auth Configuration - Deleting /opt/jans/python/libs/Casa.py - Deleting /opt/jans/python/libs/casa-external_fido2.py - Deleting /opt/jans/python/libs/casa-external_otp.py - Deleting /opt/jans/python/libs/casa-external_super_gluu.py - Deleting /opt/jans/python/libs/casa-external_twilio_sms.py - Deleting casa client from db backend - Deleting casa client scopes from db backend - Deleting casa configuration from db backend - Deleting script 3000-F75A from db backend - Deleting /opt/jans/jetty/casa Uninstalling Gluu Admin-UI - Deleting Gluu Flex Admin UI Client 2001.732c7b51-57c4-48a5-b64d-8718b3e043bb - Removing Admin UI directives from apache configuration - Deleting /opt/jans/jetty/jans-config-api/custom/libs/gluu-flex-admin-ui-plugin.jar - Removing plugin /opt/jans/jetty/jans-config-api/custom/libs/gluu-flex-admin-ui-plugin.jar from Jans Config API Configuration - Deleting /opt/jans/jetty/jans-config-api/custom/config/log4j2-adminui.xml - Deleting /opt/jans/jetty/jans-config-api/custom/config/log4j2.xml - Rewriting Jans CLI init file for plugins - Deleting /srv/www/htdocs/admin Disabling script A51E-76DA Restarting Apache Restarting Jans Auth Restarting Janssen Config Api Uninstall Janssen Packages # The command below removes and uninstall the jans package sudo python3 /opt/jans/jans-setup/install.py -uninstall output will be like this: sudo python3 /opt/jans/jans-setup/install.py -uninstall -yes --keep-downloads --keep-setup This process is irreversible. You will lose all data related to Janssen Server. Are you sure to uninstall Janssen Server? [ yes/N ] yes Uninstalling Jannsen Server... Removing /etc/default/jans-config-api Stopping jans-config-api Removing /etc/default/jans-auth Stopping jans-auth Removing /etc/default/jans-fido2 Stopping jans-fido2 Removing /etc/default/jans-scim Stopping jans-scim Removing /etc/default/jans-cache-refresh Stopping jans-cache-refresh Executing rm -r -f /etc/certs Executing rm -r -f /etc/jans Executing rm -r -f /opt/jans Executing rm -r -f /opt/amazon-corretto* Executing rm -r -f /opt/jre Executing rm -r -f /opt/node* Executing rm -r -f /opt/jetty* Executing rm -r -f /opt/jython* Executing rm -r -f /opt/dist Removing /etc/apache2/vhosts.d/_https_jans.conf Second uninstall the package: You should see the package with: sudo rpm -qa | grep flex Remove package with: sudo zypper remove flex Updating Admin UI # To update the Admin UI in an existing Flex installation, execute this command: sudo python3 /opt/jans/jans-setup/flex/flex-linux-setup/flex_setup.py --update-admin-ui","title":"SUSE"},{"location":"install/vm-install/suse/#install-gluu-flex-on-suse-linux","text":"This is a step-by-step guide for installation and uninstallation of Gluu Flex on SUSE Linux distributions","title":"Install Gluu Flex On SUSE Linux"},{"location":"install/vm-install/suse/#prerequisites","text":"Ensure that the OS platform is one of the supported versions VM should meet VM system requirements Make sure that if SELinux is installed then it is put into permissive mode If the server firewall is running, make sure you allow https , which is needed for OpenID and FIDO. sudo firewall-cmd --permanent --zone = public --add-service = https sudo firewall-cmd --reload for SUSE Linux Enterprise(SLES) we need to enable PackageHub as per OS version and architecture sudo SUSEConnect -p PackageHub/15.4/x86_64 Please obtain an SSA to trial Flex, after which you are issued a JWT that you can use during installation. SSA should be stored in a text file on an accessible path.","title":"Prerequisites"},{"location":"install/vm-install/suse/#install-the-package","text":"","title":"Install the Package"},{"location":"install/vm-install/suse/#download-and-verify-the-release-package","text":"Download the release package from the GitHub FLEX Releases wget https://github.com/GluuFederation/flex/releases/download/v5.1.6.nightly/flex-5.1.6.nightly-suse15.x86_64.rpm -P ~/ GPG key is used to ensure the authenticity of the downloaded package during the installation process. If the key is not found, the installation step would fail. Use the commands below to download and import the GPG key. wget https://github.com/GluuFederation/flex/files/11814579/automation-flex-public-gpg.zip unzip automation-flex-public-gpg.zip sudo rpm -import automation-flex-public-gpg.asc Verify the integrity of the downloaded package using published sha256sum . Download the sha256sum file for the package wget https://github.com/GluuFederation/flex/releases/download/v5.1.6.nightly/flex-5.1.6.nightly-suse15.x86_64.rpm.sha256sum -P ~/ Verify package integrity sha256sum -c flex-5.1.6.nightly-suse15.x86_64.rpm.sha256sum You should see: flex-5.1.6.nightly-suse15.x86_64.rpm: ok","title":"Download and Verify the Release Package"},{"location":"install/vm-install/suse/#install-the-release-package","text":"Use SUSE zypper to install sudo zypper install ~/flex-5.1.6.nightly-suse15.x86_64.rpm","title":"Install the Release Package"},{"location":"install/vm-install/suse/#run-the-setup-script","text":"Run the setup script: Execute the setup script with command below: sudo python3 /opt/jans/jans-setup/flex/flex-linux-setup/flex_setup.py If Admin-UI component is being installed, then the script will require SSA input, either as text or as a file path. This should be the SSA or file which was acquired as part of prerequisite step . Install Admin UI [Y/n]: y Please enter path of file containing SSA or paste SSA (q to exit): Alternatively, for SSA file can be passed as a parameter to the setup script as below. sudo python3 /opt/jans/jans-setup/flex/flex-linux-setup/flex_setup.py -admin-ui-ssa [ filename ]","title":"Run the setup script"},{"location":"install/vm-install/suse/#verify-and-access-the-installation","text":"Verify that installation has been successful and all installed components are accessible using the steps below: Log in to Text User Interface (TUI) /opt/jans/jans-cli/jans_cli_tui.py TUI is a text-based configuration tool for Gluu Flex Server. Log into Admin-UI using URI below https://FQDN/admin When troubleshooting issues with Admin UI access, it's advisable to check the logs , refer to the FAQ , and review service dependencies for potential solutions. Access Casa using URI below https://FQDN/jans-casa","title":"Verify and Access the Installation"},{"location":"install/vm-install/suse/#enabling-https","text":"To enable communication with Janssen Server over TLS (https) in a production environment, Janssen Server needs details about CA certificate. Update the HTTPS cofiguration file https_jans.conf as shown below: Note Want to use Let's Encrypt to get a certificate? Follow this guide . Open _https_jans.conf sudo vi /etc/apache2/vhosts.d/_https_jans.conf ``` - Update ` SSLCertificateFile ` and ` SSLCertificateKeyFile ` parameters values ``` bash SSLCertificateFile location_of_fullchain.pem SSLCertificateKeyFile location_of_privkey.pem Restart apache service for changes to take effect sudo /usr/sbin/rcapache2 restart","title":"Enabling HTTPS"},{"location":"install/vm-install/suse/#uninstallation","text":"Removing Flex is a two step process: Uninstall Gluu Flex and Uninstall Janssen Packages Remove Gluu Packages If you have not run the setup script, you can skip step 1 and just remove the package. First use the command below to uninstall the Gluu Flex server sudo python3 /opt/jans/jans-setup/flex/flex-linux-setup/flex_setup.py --remove-flex the output will be like this: sudo python3 /opt/jans/jans-setup/flex/flex-linux-setup/flex_setup.py --remove-flex This process is irreversible. Gluu Flex Components will be removed Are you sure to uninstall Gluu Flex? [yes/N] yes Profile was detected as jans. Log Files: /opt/jans/jans-setup/logs/flex-setup.log /opt/jans/jans-setup/logs/flex-setup-error.log /opt/jans/jans-setup/setup_app/pylib/jwt/utils.py:7: CryptographyDeprecationWarning: Python 3.6 is no longer supported by the Python core team. Therefore, support for it is deprecated in cryptography and will be removed in a future release. from cryptography.hazmat.primitives.asymmetric.ec import EllipticCurve Please wait while collecting properties... Uninstalling Gluu Casa - Deleting /etc/default/casa - Deleting /etc/systemd/system/casa.service - Removing casa directives from apache configuration - Deleting /opt/jans/jetty/jans-auth/custom/libs/casa-config.jar - Removing plugin /opt/jans/jetty/jans-auth/custom/libs/casa-config.jar from Jans Auth Configuration - Deleting /opt/jans/python/libs/Casa.py - Deleting /opt/jans/python/libs/casa-external_fido2.py - Deleting /opt/jans/python/libs/casa-external_otp.py - Deleting /opt/jans/python/libs/casa-external_super_gluu.py - Deleting /opt/jans/python/libs/casa-external_twilio_sms.py - Deleting casa client from db backend - Deleting casa client scopes from db backend - Deleting casa configuration from db backend - Deleting script 3000-F75A from db backend - Deleting /opt/jans/jetty/casa Uninstalling Gluu Admin-UI - Deleting Gluu Flex Admin UI Client 2001.732c7b51-57c4-48a5-b64d-8718b3e043bb - Removing Admin UI directives from apache configuration - Deleting /opt/jans/jetty/jans-config-api/custom/libs/gluu-flex-admin-ui-plugin.jar - Removing plugin /opt/jans/jetty/jans-config-api/custom/libs/gluu-flex-admin-ui-plugin.jar from Jans Config API Configuration - Deleting /opt/jans/jetty/jans-config-api/custom/config/log4j2-adminui.xml - Deleting /opt/jans/jetty/jans-config-api/custom/config/log4j2.xml - Rewriting Jans CLI init file for plugins - Deleting /srv/www/htdocs/admin Disabling script A51E-76DA Restarting Apache Restarting Jans Auth Restarting Janssen Config Api","title":"Uninstallation"},{"location":"install/vm-install/suse/#uninstall-janssen-packages","text":"The command below removes and uninstall the jans package sudo python3 /opt/jans/jans-setup/install.py -uninstall output will be like this: sudo python3 /opt/jans/jans-setup/install.py -uninstall -yes --keep-downloads --keep-setup This process is irreversible. You will lose all data related to Janssen Server. Are you sure to uninstall Janssen Server? [ yes/N ] yes Uninstalling Jannsen Server... Removing /etc/default/jans-config-api Stopping jans-config-api Removing /etc/default/jans-auth Stopping jans-auth Removing /etc/default/jans-fido2 Stopping jans-fido2 Removing /etc/default/jans-scim Stopping jans-scim Removing /etc/default/jans-cache-refresh Stopping jans-cache-refresh Executing rm -r -f /etc/certs Executing rm -r -f /etc/jans Executing rm -r -f /opt/jans Executing rm -r -f /opt/amazon-corretto* Executing rm -r -f /opt/jre Executing rm -r -f /opt/node* Executing rm -r -f /opt/jetty* Executing rm -r -f /opt/jython* Executing rm -r -f /opt/dist Removing /etc/apache2/vhosts.d/_https_jans.conf Second uninstall the package: You should see the package with: sudo rpm -qa | grep flex Remove package with: sudo zypper remove flex","title":"Uninstall Janssen Packages"},{"location":"install/vm-install/suse/#updating-admin-ui","text":"To update the Admin UI in an existing Flex installation, execute this command: sudo python3 /opt/jans/jans-setup/flex/flex-linux-setup/flex_setup.py --update-admin-ui","title":"Updating Admin UI"},{"location":"install/vm-install/ubuntu/","tags":["administration","installation","vm","Ubuntu"],"text":"Install Gluu Flex On Ubuntu Linux # This is a step-by-step guide for installation and uninstallation of Gluu Flex on Ubuntu Linux Prerequisites # Ensure that the OS platform is one of the supported versions VM should meet VM system requirements Make sure that if SELinux is installed then it is put into permissive mode If the server firewall is running, make sure you allow https , which is needed for OpenID and FIDO. sudo ufw allow https Please obtain an SSA to trial Flex, after which you are issued a JWT that you can use during installation. SSA should be stored in a text file on an accessible path. Install the Package # Download and Verify the Release Package # Download the release package from the GitHub FLEX Releases . Choose the correct command from below based on the OS version. #Ubuntu 22.04 wget https://github.com/GluuFederation/flex/releases/download/v5.1.6.nightly/flex_5.1.6.nightly.ubuntu22.04_amd64.deb -P /tmp #Ubuntu 20.04 wget https://github.com/GluuFederation/flex/releases/download/v5.1.6.nightly/flex_5.1.6.nightly.ubuntu20.04_amd64.deb -P /tmp GPG key is used to ensure the authenticity of the downloaded package during the installation process. If the key is not found, the installation step would fail. Use the commands below to download and import the GPG key. wget https://github.com/GluuFederation/flex/files/11814579/automation-flex-public-gpg.zip unzip automation-flex-public-gpg.zip ; sudo gpg --import automation-flex-public-gpg.asc ; Verify the integrity of the downloaded package using published sha256sum . Download the sha256sum file for the package. Choose the correct command from below based on the OS version. #Ubuntu 22.04 wget https://github.com/GluuFederation/flex/releases/download/v5.1.6.nightly/flex_5.1.6.nightly.ubuntu22.04_amd64.deb.sha256sum -P /tmp #Ubuntu 20.04 wget https://github.com/GluuFederation/flex/releases/download/v5.1.6.nightly/flex_5.1.6.nightly.ubuntu20.04_amd64.deb.sha256sum -P /tmp Verify package integrity of the package that has been downloaded by checking hash. Run the command below from the directory where the downloaded package and the .sha256sum files are located. Choose the correct command from below based on the OS version. #Ubuntu 22.04 cd /tmp sha256sum -c flex_5.1.6.nightly.ubuntu22.04_amd64.deb.sha256sum #Ubuntu 20.04 cd /tmp sha256sum -c flex_5.1.6.nightly.ubuntu20.04_amd64.deb.sha256sum Output similar to below should confirm the integrity of the downloaded package. flex_5.1.6.nightly.ubuntu_amd64.deb: ok Install the Release Package # Choose the correct command from below based on the OS version. #Ubuntu 22.04 apt install -y /tmp/flex_5.1.6.nightly.ubuntu22.04_amd64.deb #Ubuntu 20.04 apt install -y /tmp/flex_5.1.6.nightly.ubuntu20.04_amd64.deb Run the setup script # Execute the setup script with command below: sudo python3 /opt/jans/jans-setup/flex/flex-linux-setup/flex_setup.py If Admin-UI component is being installed, then the script will require SSA input, either as text or as a file path. This should be the SSA or file which was acquired as part of prerequisite step . Install Admin UI [Y/n]: y Please enter path of file containing SSA or paste SSA (q to exit): Alternatively, for SSA file can be passed as a parameter to the setup script as below. sudo python3 /opt/jans/jans-setup/flex/flex-linux-setup/flex_setup.py -admin-ui-ssa [ filename ] Verify and Access the Installation # Verify that installation has been successful and all installed components are accessible using the steps below: Log in to Text User Interface (TUI) /opt/jans/jans-cli/jans_cli_tui.py TUI is a text-based configuration tool for Gluu Flex Server. Log into Admin-UI using URI below https://FQDN/admin When troubleshooting issues with Admin UI access, it's advisable to check the logs , refer to the FAQ , and review service dependencies for potential solutions. Access Casa using URI below https://FQDN/jans-casa Enabling HTTPS # To enable communication with Janssen Server over TLS (https) in a production environment, Janssen Server needs details about CA certificate. Note Want to use Let's Encrypt to get a certificate? Follow this guide . Uninstallation # Removing Flex is a two step process: Uninstall Gluu Flex Uninstall Janssen Packages If you have not run the setup script, you can skip step 1 and just remove the package. Uninstall Gluu Flex # Use the command below to uninstall the Gluu Flex server python3 /opt/jans/jans-setup/flex/flex-linux-setup/flex_setup.py --remove-flex Output: root@manojs1978-cute-ram:~# python3 /opt/jans/jans-setup/flex/flex-linux-setup/flex_setup.py --remove-flex This process is irreversible. Gluu Flex Components will be removed Are you sure to uninstall Gluu Flex? [yes/N] yes Profile was detected as jans. Log Files: /opt/jans/jans-setup/logs/flex-setup.log /opt/jans/jans-setup/logs/flex-setup-error.log Please wait while collecting properties... Uninstalling Gluu Casa - Deleting /etc/default/casa - Deleting /etc/systemd/system/casa.service - Removing casa directives from apache configuration - Deleting /opt/jans/jetty/jans-auth/custom/libs/casa-config.jar - Removing plugin /opt/jans/jetty/jans-auth/custom/libs/casa-config.jar from Jans Auth Configuration - Deleting /opt/jans/python/libs/Casa.py - Deleting /opt/jans/python/libs/casa-external_fido2.py - Deleting /opt/jans/python/libs/casa-external_otp.py - Deleting /opt/jans/python/libs/casa-external_super_gluu.py - Deleting /opt/jans/python/libs/casa-external_twilio_sms.py - Deleting casa client from db backend - Deleting casa client scopes from db backend - Deleting casa configuration from db backend - Deleting script 3000-F75A from db backend - Deleting /opt/jans/jetty/casa Uninstalling Gluu Admin-UI - Deleting Gluu Flex Admin UI Client 2001.e7989c7e-09b5-4e39-a7c9-a78017127cf0 - Removing Admin UI directives from apache configuration - Deleting /opt/jans/jetty/jans-config-api/custom/libs/gluu-flex-admin-ui-plugin.jar - Removing plugin /opt/jans/jetty/jans-config-api/custom/libs/gluu-flex-admin-ui-plugin.jar from Jans Config API Configuration - Deleting /opt/jans/jetty/jans-config-api/custom/config/log4j2-adminui.xml - Deleting /opt/jans/jetty/jans-config-api/custom/config/log4j2.xml - Rewriting Jans CLI init file for plugins - Deleting /var/www/html/admin Disabling script A51E-76DA Restarting Apache Restarting Jans Auth Restarting Janssen Config Api Uninstall Janssen Packages # The command below removes and uninstall the jans package python3 /opt/jans/jans-setup/install.py -uninstall Output : root@manojs1978-cute-ram:~# python3 /opt/jans/jans-setup/install.py -uninstall This process is irreversible. You will lose all data related to Janssen Server. Are you sure to uninstall Janssen Server? [yes/N] yes Uninstalling Jannsen Server... Removing /etc/default/jans-config-api Stopping jans-config-api Removing /etc/default/jans-auth Stopping jans-auth Removing /etc/default/jans-fido2 Stopping jans-fido2 Removing /etc/default/jans-scim Stopping jans-scim Removing /etc/default/jans-cache-refresh Stopping jans-cache-refresh Stopping OpenDj Server Stopping Server... [23/Jun/2023:09:10:27 +0000] category=BACKEND severity=NOTICE msgID=370 msg=The backend userRoot is now taken offline [23/Jun/2023:09:10:28 +0000] category=BACKEND severity=NOTICE msgID=370 msg=The backend site is now taken offline [23/Jun/2023:09:10:28 +0000] category=BACKEND severity=NOTICE msgID=370 msg=The backend metric is now taken offline [23/Jun/2023:09:10:28 +0000] category=CORE severity=NOTICE msgID=203 msg=The Directory Server is now stopped Executing rm -r -f /etc/certs Executing rm -r -f /etc/jans Executing rm -r -f /opt/jans Executing rm -r -f /opt/amazon-corretto* Executing rm -r -f /opt/jre Executing rm -r -f /opt/node* Executing rm -r -f /opt/jetty* Executing rm -r -f /opt/jython* Executing rm -r -f /opt/opendj Executing rm -r -f /opt/dist Removing /etc/apache2/sites-enabled/https_jans.conf Removing /etc/apache2/sites-available/https_jans.conf Remove Gluu Flex Packages: # List existing Gluu Flex packages with: sudo apt list --installed | grep flex Remove packages: sudo apt remove Uninstalling Admin UI # To uninstall the Admin UI from your Flex installation, execute this command: sudo python3 /opt/jans/jans-setup/flex/flex-linux-setup/flex_setup.py --remove-flex Updating Admin UI # To update the Admin UI in an existing Flex installation, execute this command: sudo python3 /opt/jans/jans-setup/flex/flex-linux-setup/flex_setup.py --update-admin-ui","title":"Ubuntu"},{"location":"install/vm-install/ubuntu/#install-gluu-flex-on-ubuntu-linux","text":"This is a step-by-step guide for installation and uninstallation of Gluu Flex on Ubuntu Linux","title":"Install Gluu Flex On Ubuntu Linux"},{"location":"install/vm-install/ubuntu/#prerequisites","text":"Ensure that the OS platform is one of the supported versions VM should meet VM system requirements Make sure that if SELinux is installed then it is put into permissive mode If the server firewall is running, make sure you allow https , which is needed for OpenID and FIDO. sudo ufw allow https Please obtain an SSA to trial Flex, after which you are issued a JWT that you can use during installation. SSA should be stored in a text file on an accessible path.","title":"Prerequisites"},{"location":"install/vm-install/ubuntu/#install-the-package","text":"","title":"Install the Package"},{"location":"install/vm-install/ubuntu/#download-and-verify-the-release-package","text":"Download the release package from the GitHub FLEX Releases . Choose the correct command from below based on the OS version. #Ubuntu 22.04 wget https://github.com/GluuFederation/flex/releases/download/v5.1.6.nightly/flex_5.1.6.nightly.ubuntu22.04_amd64.deb -P /tmp #Ubuntu 20.04 wget https://github.com/GluuFederation/flex/releases/download/v5.1.6.nightly/flex_5.1.6.nightly.ubuntu20.04_amd64.deb -P /tmp GPG key is used to ensure the authenticity of the downloaded package during the installation process. If the key is not found, the installation step would fail. Use the commands below to download and import the GPG key. wget https://github.com/GluuFederation/flex/files/11814579/automation-flex-public-gpg.zip unzip automation-flex-public-gpg.zip ; sudo gpg --import automation-flex-public-gpg.asc ; Verify the integrity of the downloaded package using published sha256sum . Download the sha256sum file for the package. Choose the correct command from below based on the OS version. #Ubuntu 22.04 wget https://github.com/GluuFederation/flex/releases/download/v5.1.6.nightly/flex_5.1.6.nightly.ubuntu22.04_amd64.deb.sha256sum -P /tmp #Ubuntu 20.04 wget https://github.com/GluuFederation/flex/releases/download/v5.1.6.nightly/flex_5.1.6.nightly.ubuntu20.04_amd64.deb.sha256sum -P /tmp Verify package integrity of the package that has been downloaded by checking hash. Run the command below from the directory where the downloaded package and the .sha256sum files are located. Choose the correct command from below based on the OS version. #Ubuntu 22.04 cd /tmp sha256sum -c flex_5.1.6.nightly.ubuntu22.04_amd64.deb.sha256sum #Ubuntu 20.04 cd /tmp sha256sum -c flex_5.1.6.nightly.ubuntu20.04_amd64.deb.sha256sum Output similar to below should confirm the integrity of the downloaded package. flex_5.1.6.nightly.ubuntu_amd64.deb: ok","title":"Download and Verify the Release Package"},{"location":"install/vm-install/ubuntu/#install-the-release-package","text":"Choose the correct command from below based on the OS version. #Ubuntu 22.04 apt install -y /tmp/flex_5.1.6.nightly.ubuntu22.04_amd64.deb #Ubuntu 20.04 apt install -y /tmp/flex_5.1.6.nightly.ubuntu20.04_amd64.deb","title":"Install the Release Package"},{"location":"install/vm-install/ubuntu/#run-the-setup-script","text":"Execute the setup script with command below: sudo python3 /opt/jans/jans-setup/flex/flex-linux-setup/flex_setup.py If Admin-UI component is being installed, then the script will require SSA input, either as text or as a file path. This should be the SSA or file which was acquired as part of prerequisite step . Install Admin UI [Y/n]: y Please enter path of file containing SSA or paste SSA (q to exit): Alternatively, for SSA file can be passed as a parameter to the setup script as below. sudo python3 /opt/jans/jans-setup/flex/flex-linux-setup/flex_setup.py -admin-ui-ssa [ filename ]","title":"Run the setup script"},{"location":"install/vm-install/ubuntu/#verify-and-access-the-installation","text":"Verify that installation has been successful and all installed components are accessible using the steps below: Log in to Text User Interface (TUI) /opt/jans/jans-cli/jans_cli_tui.py TUI is a text-based configuration tool for Gluu Flex Server. Log into Admin-UI using URI below https://FQDN/admin When troubleshooting issues with Admin UI access, it's advisable to check the logs , refer to the FAQ , and review service dependencies for potential solutions. Access Casa using URI below https://FQDN/jans-casa","title":"Verify and Access the Installation"},{"location":"install/vm-install/ubuntu/#enabling-https","text":"To enable communication with Janssen Server over TLS (https) in a production environment, Janssen Server needs details about CA certificate. Note Want to use Let's Encrypt to get a certificate? Follow this guide .","title":"Enabling HTTPS"},{"location":"install/vm-install/ubuntu/#uninstallation","text":"Removing Flex is a two step process: Uninstall Gluu Flex Uninstall Janssen Packages If you have not run the setup script, you can skip step 1 and just remove the package.","title":"Uninstallation"},{"location":"install/vm-install/ubuntu/#uninstall-gluu-flex","text":"Use the command below to uninstall the Gluu Flex server python3 /opt/jans/jans-setup/flex/flex-linux-setup/flex_setup.py --remove-flex Output: root@manojs1978-cute-ram:~# python3 /opt/jans/jans-setup/flex/flex-linux-setup/flex_setup.py --remove-flex This process is irreversible. Gluu Flex Components will be removed Are you sure to uninstall Gluu Flex? [yes/N] yes Profile was detected as jans. Log Files: /opt/jans/jans-setup/logs/flex-setup.log /opt/jans/jans-setup/logs/flex-setup-error.log Please wait while collecting properties... Uninstalling Gluu Casa - Deleting /etc/default/casa - Deleting /etc/systemd/system/casa.service - Removing casa directives from apache configuration - Deleting /opt/jans/jetty/jans-auth/custom/libs/casa-config.jar - Removing plugin /opt/jans/jetty/jans-auth/custom/libs/casa-config.jar from Jans Auth Configuration - Deleting /opt/jans/python/libs/Casa.py - Deleting /opt/jans/python/libs/casa-external_fido2.py - Deleting /opt/jans/python/libs/casa-external_otp.py - Deleting /opt/jans/python/libs/casa-external_super_gluu.py - Deleting /opt/jans/python/libs/casa-external_twilio_sms.py - Deleting casa client from db backend - Deleting casa client scopes from db backend - Deleting casa configuration from db backend - Deleting script 3000-F75A from db backend - Deleting /opt/jans/jetty/casa Uninstalling Gluu Admin-UI - Deleting Gluu Flex Admin UI Client 2001.e7989c7e-09b5-4e39-a7c9-a78017127cf0 - Removing Admin UI directives from apache configuration - Deleting /opt/jans/jetty/jans-config-api/custom/libs/gluu-flex-admin-ui-plugin.jar - Removing plugin /opt/jans/jetty/jans-config-api/custom/libs/gluu-flex-admin-ui-plugin.jar from Jans Config API Configuration - Deleting /opt/jans/jetty/jans-config-api/custom/config/log4j2-adminui.xml - Deleting /opt/jans/jetty/jans-config-api/custom/config/log4j2.xml - Rewriting Jans CLI init file for plugins - Deleting /var/www/html/admin Disabling script A51E-76DA Restarting Apache Restarting Jans Auth Restarting Janssen Config Api","title":"Uninstall Gluu Flex"},{"location":"install/vm-install/ubuntu/#uninstall-janssen-packages","text":"The command below removes and uninstall the jans package python3 /opt/jans/jans-setup/install.py -uninstall Output : root@manojs1978-cute-ram:~# python3 /opt/jans/jans-setup/install.py -uninstall This process is irreversible. You will lose all data related to Janssen Server. Are you sure to uninstall Janssen Server? [yes/N] yes Uninstalling Jannsen Server... Removing /etc/default/jans-config-api Stopping jans-config-api Removing /etc/default/jans-auth Stopping jans-auth Removing /etc/default/jans-fido2 Stopping jans-fido2 Removing /etc/default/jans-scim Stopping jans-scim Removing /etc/default/jans-cache-refresh Stopping jans-cache-refresh Stopping OpenDj Server Stopping Server... [23/Jun/2023:09:10:27 +0000] category=BACKEND severity=NOTICE msgID=370 msg=The backend userRoot is now taken offline [23/Jun/2023:09:10:28 +0000] category=BACKEND severity=NOTICE msgID=370 msg=The backend site is now taken offline [23/Jun/2023:09:10:28 +0000] category=BACKEND severity=NOTICE msgID=370 msg=The backend metric is now taken offline [23/Jun/2023:09:10:28 +0000] category=CORE severity=NOTICE msgID=203 msg=The Directory Server is now stopped Executing rm -r -f /etc/certs Executing rm -r -f /etc/jans Executing rm -r -f /opt/jans Executing rm -r -f /opt/amazon-corretto* Executing rm -r -f /opt/jre Executing rm -r -f /opt/node* Executing rm -r -f /opt/jetty* Executing rm -r -f /opt/jython* Executing rm -r -f /opt/opendj Executing rm -r -f /opt/dist Removing /etc/apache2/sites-enabled/https_jans.conf Removing /etc/apache2/sites-available/https_jans.conf","title":"Uninstall Janssen Packages"},{"location":"install/vm-install/ubuntu/#remove-gluu-flex-packages","text":"List existing Gluu Flex packages with: sudo apt list --installed | grep flex Remove packages: sudo apt remove ","title":"Remove Gluu Flex Packages:"},{"location":"install/vm-install/ubuntu/#uninstalling-admin-ui","text":"To uninstall the Admin UI from your Flex installation, execute this command: sudo python3 /opt/jans/jans-setup/flex/flex-linux-setup/flex_setup.py --remove-flex","title":"Uninstalling Admin UI"},{"location":"install/vm-install/ubuntu/#updating-admin-ui","text":"To update the Admin UI in an existing Flex installation, execute this command: sudo python3 /opt/jans/jans-setup/flex/flex-linux-setup/flex_setup.py --update-admin-ui","title":"Updating Admin UI"},{"location":"install/vm-install/vm-requirements/","text":"VM System Requirements # Supported Versions # Gluu Flex currently provides packages for these Linux distros: Ubuntu (versions: 20.04 and 22.04) SUSE Distributions SUSE Linux Enterprise Server (SLES) 15 openSUSE Leap 15.5 openSUSE Tumbleweed RedHat Enterprise Linux (version: 8) Note This document is intended exclusively for dev and staging environments. For production deployment on a VM, refer to this documentation which utilizes Rancher and Helm deployments. Hardware Requirements # A single-VM deployment is where all services are running on one server. Although, the requirements can vary based on the size of the data and the required concurrency, the following guidelines can help you plan: 8 GB RAM 4 CPU 20 GB Disk Port Configuration # Gluu Flex requires the following ports to be open for incoming connections. Port Protocol Notes 443 TCP TLS/HTTP You may want to use a redirect on port 80 to 443, although it is not required. Of course you will also need some way to login to your server, but that is out of scope of these docs. Check your server firewall documentation to configure your firewall to allow https . Hostname / IP Address Configuration # It is recommended that you use a static ip address for Gluu Flex. Your server should also return the hostname for the hostname command, it's recommended that you add the hostname to the /etc/hosts file. File Descriptor Configuration (FD) # Like most database and Internet servers, you must have at least 65k file descriptors. If you don't, your server will hang. First, check the current file descriptor limit using command below. If the existing FD limit exceeds 65535, then you're good. # cat /proc/sys/fs/file-max If FD limit is less than 65535 (e.g. 1024), then follow the steps below to increase the value. 1) Set soft and hard limits by adding the following lines in the /etc/security/limits.conf file * soft nofile 65535 * hard nofile 262144 2) Add the following lines to /etc/pam.d/login if not already present session required pam_limits.so 3) Increase the FD limit in /proc/sys/fs/file-max echo 65535 > /proc/sys/fs/file-max** 4) Use the ulimit command to set the FD limit to the hard limit specified in /etc/security/limits.conf . If setting to hard limit doesn't work, then try to set it to the soft limit. ulimit -n 262144 5) Restart the system","title":"VM System Requirements"},{"location":"install/vm-install/vm-requirements/#vm-system-requirements","text":"","title":"VM System Requirements"},{"location":"install/vm-install/vm-requirements/#supported-versions","text":"Gluu Flex currently provides packages for these Linux distros: Ubuntu (versions: 20.04 and 22.04) SUSE Distributions SUSE Linux Enterprise Server (SLES) 15 openSUSE Leap 15.5 openSUSE Tumbleweed RedHat Enterprise Linux (version: 8) Note This document is intended exclusively for dev and staging environments. For production deployment on a VM, refer to this documentation which utilizes Rancher and Helm deployments.","title":"Supported Versions"},{"location":"install/vm-install/vm-requirements/#hardware-requirements","text":"A single-VM deployment is where all services are running on one server. Although, the requirements can vary based on the size of the data and the required concurrency, the following guidelines can help you plan: 8 GB RAM 4 CPU 20 GB Disk","title":"Hardware Requirements"},{"location":"install/vm-install/vm-requirements/#port-configuration","text":"Gluu Flex requires the following ports to be open for incoming connections. Port Protocol Notes 443 TCP TLS/HTTP You may want to use a redirect on port 80 to 443, although it is not required. Of course you will also need some way to login to your server, but that is out of scope of these docs. Check your server firewall documentation to configure your firewall to allow https .","title":"Port Configuration"},{"location":"install/vm-install/vm-requirements/#hostname-ip-address-configuration","text":"It is recommended that you use a static ip address for Gluu Flex. Your server should also return the hostname for the hostname command, it's recommended that you add the hostname to the /etc/hosts file.","title":"Hostname / IP Address Configuration"},{"location":"install/vm-install/vm-requirements/#file-descriptor-configuration-fd","text":"Like most database and Internet servers, you must have at least 65k file descriptors. If you don't, your server will hang. First, check the current file descriptor limit using command below. If the existing FD limit exceeds 65535, then you're good. # cat /proc/sys/fs/file-max If FD limit is less than 65535 (e.g. 1024), then follow the steps below to increase the value. 1) Set soft and hard limits by adding the following lines in the /etc/security/limits.conf file * soft nofile 65535 * hard nofile 262144 2) Add the following lines to /etc/pam.d/login if not already present session required pam_limits.so 3) Increase the FD limit in /proc/sys/fs/file-max echo 65535 > /proc/sys/fs/file-max** 4) Use the ulimit command to set the FD limit to the hard limit specified in /etc/security/limits.conf . If setting to hard limit doesn't work, then try to set it to the soft limit. ulimit -n 262144 5) Restart the system","title":"File Descriptor Configuration (FD)"},{"location":"openbanking/","text":"Gluu Open Banking Identity Platform # Overview # The Gluu Open Banking Identity Platform is a specific profile of the Gluu Server that is packaged and configured for certain use cases: Dynamic Client Registration using software statements Payment Authorization Identity - eKYC Client Initiated Authentication (mobile/out-of-band) Other services needed by enterprises--but not by banks--have been disabled. The goal is to reduce the security surface area to make the platform easy to deploy, easy to keep up to date, and easy to rollout new features with zero downtime. This is a cloud-native distribution. Cloud-native is essential for auto-scaling, high availability, and operational automation. For development and testing we also support its VM distribution, where the Installation Section has more details about it. This distribution of Gluu is based on the Linux Foundation Janssen Project at the Linux Foundation, the most certified OpenID Platform available. Components # Open Banking OpenID Provider : Based on the Janssen Auth-Server, this internet-facing component provides the FAPI OpenID Connect API for dynamic client registration, transaction authorization, and CIBA. Config API : Service which configures the OpenID Provider. The Client must present an access token authorized by a trusted issuer with certain scopes. Cloud Database : Database used to store configuration, client metadata, tokens, and other information required for the operation of the OpenID Provider. Open Banking API Gateway : An Internet facing gateway for the core open banking API, should enforce the presence of a token with certain scopes. Open Banking API : The core banking API. Internal Authentication and Consent Service : An OpenID Provider, SAML IDP, or another authentication service that provides access to actual customer information. This service may handle the consent, or delegate consent to another service. User Accounts : A database where the user account information is held Bank Regulatory Directory : This is hosted by the federation operator which publishes public key material and other metadata about participants in the open banking ecosystem. Fintech / Payment Processor : A service that wants to call the Open Banking API or to get data or to process a payment. PKI infrastructure # Cloud-Native Architecture #","title":"Overview"},{"location":"openbanking/#gluu-open-banking-identity-platform","text":"","title":"Gluu Open Banking Identity Platform"},{"location":"openbanking/#overview","text":"The Gluu Open Banking Identity Platform is a specific profile of the Gluu Server that is packaged and configured for certain use cases: Dynamic Client Registration using software statements Payment Authorization Identity - eKYC Client Initiated Authentication (mobile/out-of-band) Other services needed by enterprises--but not by banks--have been disabled. The goal is to reduce the security surface area to make the platform easy to deploy, easy to keep up to date, and easy to rollout new features with zero downtime. This is a cloud-native distribution. Cloud-native is essential for auto-scaling, high availability, and operational automation. For development and testing we also support its VM distribution, where the Installation Section has more details about it. This distribution of Gluu is based on the Linux Foundation Janssen Project at the Linux Foundation, the most certified OpenID Platform available.","title":"Overview"},{"location":"openbanking/#components","text":"Open Banking OpenID Provider : Based on the Janssen Auth-Server, this internet-facing component provides the FAPI OpenID Connect API for dynamic client registration, transaction authorization, and CIBA. Config API : Service which configures the OpenID Provider. The Client must present an access token authorized by a trusted issuer with certain scopes. Cloud Database : Database used to store configuration, client metadata, tokens, and other information required for the operation of the OpenID Provider. Open Banking API Gateway : An Internet facing gateway for the core open banking API, should enforce the presence of a token with certain scopes. Open Banking API : The core banking API. Internal Authentication and Consent Service : An OpenID Provider, SAML IDP, or another authentication service that provides access to actual customer information. This service may handle the consent, or delegate consent to another service. User Accounts : A database where the user account information is held Bank Regulatory Directory : This is hosted by the federation operator which publishes public key material and other metadata about participants in the open banking ecosystem. Fintech / Payment Processor : A service that wants to call the Open Banking API or to get data or to process a payment.","title":"Components"},{"location":"openbanking/#pki-infrastructure","text":"","title":"PKI infrastructure"},{"location":"openbanking/#cloud-native-architecture","text":"","title":"Cloud-Native Architecture"},{"location":"openbanking/configuration-instructions/","text":"Generate/install keys and certs for Gluu Open Banking Identity Platform # This section covers details about setting up the keys and certificates in Cloud-Native distribution. For MTLS keys, see the document that demonstrates enabling mTLS in nginx ingress . Remember, MTLS is needed not only for the TPPs to call the authorization and token endpoints for OpenID Connect flows, but also by clients that are calling the configuration API. Add/Update Custom Scripts: # To add or update custom scripts, you can use either jans-cli or curl . jans-cli in interactive mode, option 13 enables you to manage custom scripts. For more info, see the docs . jans-cli in command line argument mode is more conducive to scripting and automation. To display the available operations for custom scripts, use config-cli.py --info CustomScripts . See the docs for more info. To use curl see these docs Note: If using VM installation you can normally find jans-cli.py in the /opt/jans/jans-cli/ folder.","title":"Configuration Instructions"},{"location":"openbanking/configuration-instructions/#generateinstall-keys-and-certs-for-gluu-open-banking-identity-platform","text":"This section covers details about setting up the keys and certificates in Cloud-Native distribution. For MTLS keys, see the document that demonstrates enabling mTLS in nginx ingress . Remember, MTLS is needed not only for the TPPs to call the authorization and token endpoints for OpenID Connect flows, but also by clients that are calling the configuration API.","title":"Generate/install keys and certs for Gluu Open Banking Identity Platform"},{"location":"openbanking/configuration-instructions/#addupdate-custom-scripts","text":"To add or update custom scripts, you can use either jans-cli or curl . jans-cli in interactive mode, option 13 enables you to manage custom scripts. For more info, see the docs . jans-cli in command line argument mode is more conducive to scripting and automation. To display the available operations for custom scripts, use config-cli.py --info CustomScripts . See the docs for more info. To use curl see these docs Note: If using VM installation you can normally find jans-cli.py in the /opt/jans/jans-cli/ folder.","title":"Add/Update Custom Scripts:"},{"location":"openbanking/curl/","text":"Managing scripts with CURL # Curl Prerequisites # Gluu open banking distribution client-id client-secret client certificate client key Getting the prerequisites # Get a client id and its associated password. Here, we will use the client id and secret created for config-api. TESTCLIENT = $( kubectl get cm cn -n --template ={{ .data.jca_client_id }} ) TESTCLIENTSECRET = $( kubectl get secret cn -n --template ={{ .data.jca_client_pw }} | base64 -d ) client.crt and client.key are the certificate and key files respectively for MTLS. Use your ca.crt and ca.key that was provided during setup to generate as many client certificates and keys as needed. If you have an existing helm deployment, you can retrieve ca.crt and ca.key using the following commands: kubectl get secret cn -n --template ={{ .data.ssl_ca_cert }} | base64 -d > ca.crt kubectl get secret cn -n --template ={{ .data.ssl_ca_key }} | base64 -d > ca.key Generate client.crt and client.key files: openssl req -new -newkey rsa:4096 -keyout client.key -out client.csr -nodes -subj '/CN=Openbanking' openssl x509 -req -sha256 -days 365 -in client.csr -CA ca.crt -CAkey ca.key -set_serial 02 -out client.crt CURL operations # The curl commands to list, add, or update custom script require a token, so first call the token endpoint to get the token using: curl -u $TESTCLIENT : $TESTCLIENTSECRET https:///jans-auth/restv1/token -d \"grant_type=client_credentials&scope=https://jans.io/oauth/config/scripts.readonly\" --cert client.crt --key client.key Example: curl -u '1801.bdfae945-b31d-4d60-8e47-16518153215:rjHoLfjfsv2G2qzGEasd1651813aIXvCi61NU' https://bank.gluu.org/jans-auth/restv1/token -d \"grant_type=client_credentials&scope=https://jans.io/oauth/config/scripts.readonly\" --cert apr22.crt --key apr22.key { \"access_token\" : \"ad34ac-8f2d-4bec-aed3-343adasda2\" , \"scope\" : \"https://jans.io/oauth/config/scripts.readonly\" , \"token_type\" : \"bearer\" , \"expires_in\" :299 } Save the access_token for use in subsequent commands. Use different scope values as per the requirement: View scripts information: https://jans.io/oauth/config/scripts.readonly Manage scripts-related information: https://jans.io/oauth/config/scripts.write Delete scripts-related information: https://jans.io/oauth/config/scripts.delete Use the obtained access token to perform further operations on custom scripts as given in subsequent text: Use the following command to display details of all the available custom scripts: curl -X GET https:///jans-config-api/api/v1/config/scripts -H \"Accept: application/json\" -H \"Authorization:Bearer \" -H \"Content-Type: application/json\" Example: curl -X GET https://bank.gluu.org/jans-config-api/api/v1/config/scripts -H \"Accept: application/json\" -H \"Authorization:Bearer ad34ac-8f2d-4bec-aed3-343adasda2\" -H \"Content-Type: application/json\" The following command will add a new custom script (Obtain token with write scope) and if it is successful it will display the added script in JSON format. The scriptformat.json file has script details according to the custom script schema. It should have the entire script inside the scriptformat.json as a string value under the script field. Converting a multiline script into a string requires converting newlines into \\n. So curl is not a suitable choice for adding new script, jans-cli is a better option. curl -X POST \"https:///jans-config-api/api/v1/config/scripts\" -H \"Accept: application/json\" -H \"Authorization:Bearer \" -H \"Content-Type: application/json\" --data @/home/user/scriptformat.json Example: curl -X POST \"https://bank.gluu.org/jans-config-api/api/v1/config/scripts\" -H \"Accept: application/json\" -H \"Authorization:Bearer ad34ac-8f2d-4bec-aed3-343adasda2\" -H \"Content-Type: application/json\" --data @/home/user/scriptformat.json","title":"Managing scripts with CURL"},{"location":"openbanking/curl/#managing-scripts-with-curl","text":"","title":"Managing scripts with CURL"},{"location":"openbanking/curl/#curl-prerequisites","text":"Gluu open banking distribution client-id client-secret client certificate client key","title":"Curl Prerequisites"},{"location":"openbanking/curl/#getting-the-prerequisites","text":"Get a client id and its associated password. Here, we will use the client id and secret created for config-api. TESTCLIENT = $( kubectl get cm cn -n --template ={{ .data.jca_client_id }} ) TESTCLIENTSECRET = $( kubectl get secret cn -n --template ={{ .data.jca_client_pw }} | base64 -d ) client.crt and client.key are the certificate and key files respectively for MTLS. Use your ca.crt and ca.key that was provided during setup to generate as many client certificates and keys as needed. If you have an existing helm deployment, you can retrieve ca.crt and ca.key using the following commands: kubectl get secret cn -n --template ={{ .data.ssl_ca_cert }} | base64 -d > ca.crt kubectl get secret cn -n --template ={{ .data.ssl_ca_key }} | base64 -d > ca.key Generate client.crt and client.key files: openssl req -new -newkey rsa:4096 -keyout client.key -out client.csr -nodes -subj '/CN=Openbanking' openssl x509 -req -sha256 -days 365 -in client.csr -CA ca.crt -CAkey ca.key -set_serial 02 -out client.crt","title":"Getting the prerequisites"},{"location":"openbanking/curl/#curl-operations","text":"The curl commands to list, add, or update custom script require a token, so first call the token endpoint to get the token using: curl -u $TESTCLIENT : $TESTCLIENTSECRET https:///jans-auth/restv1/token -d \"grant_type=client_credentials&scope=https://jans.io/oauth/config/scripts.readonly\" --cert client.crt --key client.key Example: curl -u '1801.bdfae945-b31d-4d60-8e47-16518153215:rjHoLfjfsv2G2qzGEasd1651813aIXvCi61NU' https://bank.gluu.org/jans-auth/restv1/token -d \"grant_type=client_credentials&scope=https://jans.io/oauth/config/scripts.readonly\" --cert apr22.crt --key apr22.key { \"access_token\" : \"ad34ac-8f2d-4bec-aed3-343adasda2\" , \"scope\" : \"https://jans.io/oauth/config/scripts.readonly\" , \"token_type\" : \"bearer\" , \"expires_in\" :299 } Save the access_token for use in subsequent commands. Use different scope values as per the requirement: View scripts information: https://jans.io/oauth/config/scripts.readonly Manage scripts-related information: https://jans.io/oauth/config/scripts.write Delete scripts-related information: https://jans.io/oauth/config/scripts.delete Use the obtained access token to perform further operations on custom scripts as given in subsequent text: Use the following command to display details of all the available custom scripts: curl -X GET https:///jans-config-api/api/v1/config/scripts -H \"Accept: application/json\" -H \"Authorization:Bearer \" -H \"Content-Type: application/json\" Example: curl -X GET https://bank.gluu.org/jans-config-api/api/v1/config/scripts -H \"Accept: application/json\" -H \"Authorization:Bearer ad34ac-8f2d-4bec-aed3-343adasda2\" -H \"Content-Type: application/json\" The following command will add a new custom script (Obtain token with write scope) and if it is successful it will display the added script in JSON format. The scriptformat.json file has script details according to the custom script schema. It should have the entire script inside the scriptformat.json as a string value under the script field. Converting a multiline script into a string requires converting newlines into \\n. So curl is not a suitable choice for adding new script, jans-cli is a better option. curl -X POST \"https:///jans-config-api/api/v1/config/scripts\" -H \"Accept: application/json\" -H \"Authorization:Bearer \" -H \"Content-Type: application/json\" --data @/home/user/scriptformat.json Example: curl -X POST \"https://bank.gluu.org/jans-config-api/api/v1/config/scripts\" -H \"Accept: application/json\" -H \"Authorization:Bearer ad34ac-8f2d-4bec-aed3-343adasda2\" -H \"Content-Type: application/json\" --data @/home/user/scriptformat.json","title":"CURL operations"},{"location":"openbanking/install-cn/","text":"System Requirements # Use the listing below for a detailed estimation of the minimum required resources. The table contains the default resources recommendation per service. Depending on the use of each service the resources need may increase or decrease. Service CPU Unit RAM Disk Space Processor Type Required Auth-server 2.5 2.5GB N/A 64 Bit Yes config - job 0.5 0.5GB N/A 64 Bit Yes on fresh installs persistence - job 0.5 0.5GB N/A 64 Bit Yes on fresh installs nginx 1 1GB N/A 64 Bit Yes if not ALB or Istio config-api 1 1GB N/A 64 Bit No Installation # Install using Helm(production-ready) # The below certificates and keys are needed to complete the installation. Certificate / key Description OB Issuing CA Used in nginx as a certificate authority OB Root CA Used in nginx as a certificate authority OB Signing CA Used in nginx as a certificate authority OB AS Transport key Used for mTLS. This will also be added to the JVM OB AS Transport crt Used for mTLS. This will also be added to the JVM OB AS signing crt Added to the JVM. Used in SSA Validation OB AS signing key Added to the JVM. Used in SSA Validation OB transport truststore Used in SSA Validation. Generated from OB Root CA nd Issuing CA Based on the provider/platform you're using, you can follow the docs to install your platform prerequistes, nginx-ingress, and the yaml changes needed in override.yaml based on the Gluu persistence choosed. To enable mTLS in ingress-nginx, add the following to your override.yaml : nginx-ingress : ingress : additionalAnnotations : nginx.ingress.kubernetes.io/auth-tls-verify-client : \"optional\" nginx.ingress.kubernetes.io/auth-tls-secret : \"gluu/tls-ob-ca-certificates\" nginx.ingress.kubernetes.io/auth-tls-verify-depth : \"1\" nginx.ingress.kubernetes.io/auth-tls-pass-certificate-to-upstream : \"true\" Adding these annotations will enable client certificate authentication . Enable authServerProtectedToken and authServerProtectedRegister : global auth-server : ingress : authServerProtectedToken : true authServerProtectedRegister : true Enable HTTPS During fresh installation, the config-job checks if SSL certificates and keys are mounted as files. If no mounted files are found, it attempts to download SSL certificates from the FQDN supplied. If the download is successful, an empty key file is generated. If no mounted or downloaded files are found, it generates self-signed SSL certificates, CA certificates, and keys. certificates and keys of interest in https Notes web_https.crt (nginx) web server certificate. This is commonly referred to as server.crt web_https.key (nginx) web server key. This is commonly referred to as server.key web_https.csr (nginx) web server certificate signing request. This is commonly referred to as server.csr web_https_ca.crt Certificate authority certificate that signed/signs the web server certificate. web_https_ca.key Certificate authority key that signed/signs the web server certificate. Create a secret containing the OB CA certificates (issuing, root, and signing CAs) and the OB AS transport crt. For more information read here . cat web_https_ca.crt issuingca.crt rootca.crt signingca.crt >> ca.crt kubectl create secret generic tls-ob-ca-certificates -n gluu --from-file = tls.crt = web_https.crt --from-file = tls.key = web_https.key --from-file = ca.crt = ca.crt If you have an existing helm deployment, those secrets can be retrieved and then create using the following commands: kubectl get secret cn -n gluu --template ={{ .data.ssl_ca_cert }} | base64 -d > ca.crt kubectl get secret cn -n gluu --template ={{ .data.ssl_cert }} | base64 -d > server.crt kubectl get secret cn -n gluu --template ={{ .data.ssl_key }} | base64 -d > server.key kubectl create secret generic ca-secret -n gluu --from-file = tls.crt = server.crt --from-file = tls.key = server.key --from-file = ca.crt = ca.crt Inject OBIE signed certs, keys and uri: When using OBIE signed certificates and keys, there are many objects that can be injected. The certificate signing pem file i.e obsigning.pem , the signing key i.e obsigning-oajsdij8927123.key , the certificate transport pem file i.e obtransport.pem , the transport key i.e obtransport-sdfe4234234.key , the transport truststore p12 i.e ob-transport-truststore.p12 , and the jwks uri https://mykeystore.openbanking.wow/xxxxx/xxxxx.jwks . base64 encrypt all .pem and .key files. cat obsigning.pem | base64 | tr -d '\\n' > obsigningbase64.pem cat obsigning-oajsdij8927123.key | base64 | tr -d '\\n' > obsigningbase64.key cat obtransport.pem | base64 | tr -d '\\n' > obtransportbase64.pem cat obtransport-sdfe4234234.key | base64 | tr -d '\\n' > obtransportbase64.key Generate your transport truststore or convert it to .p12 format. Please name it as ob-transport-truststore.p12 cat obissuingca.pem obrootca.pem obsigningca.pem > transport-truststore.crt keytool -importcert -file transport-truststore.crt -keystore ob-transport-truststore.p12 -alias obkeystore base64 encrypt the ob-transport-truststore.p12 cat ob-transport-truststore.p12 | base64 | tr -d '\\n' > obtransporttruststorebase64.pem Add the kid as the alias for the JKS used for the OB AS external signing crt. This is a kid value.Used in SSA Validation, kid used while encoding a JWT sent to token URL i.e XkwIzWy44xWSlcWnMiEc8iq9s2G. This kid value should exist inside the jwks uri endpoint. Add those values to override.yaml : global : # -- Open banking external signing jwks uri. Used in SSA Validation. cnObExtSigningJwksUri : \"\" # -- Open banking external signing jwks AS certificate authority string. Used in SSA Validation. This must be encoded using base64.. Used when `.global.cnObExtSigningJwksUri` is set. cnObExtSigningJwksCrt : # -- Open banking external signing jwks AS key string. Used in SSA Validation. This must be encoded using base64. Used when `.global.cnObExtSigningJwksUri` is set. cnObExtSigningJwksKey : # -- Open banking external signing jwks AS key passphrase to unlock provided key. This must be encoded using base64. Used when `.global.cnObExtSigningJwksUri` is set. cnObExtSigningJwksKeyPassPhrase : # -- Open banking external signing AS Alias. This is a kid value. Used in SSA Validation, kid used while encoding a JWT sent to token URL i.e. XkwIzWy44xWSlcWnMiEc8iq9s2G cnObExtSigningAlias : # -- Open banking signing AS kid to force the AS to use a specific signing key. i.e. Wy44xWSlcWnMiEc8iq9s2G cnObStaticSigningKeyKid : # -- Open banking AS transport crt. Used in SSA Validation. This must be encoded using base64. cnObTransportCrt : # -- Open banking AS transport key. Used in SSA Validation. This must be encoded using base64. cnObTransportKey : # -- Open banking AS transport key passphrase to unlock AS transport key. This must be encoded using base64. cnObTransportKeyPassPhrase : # -- Open banking transport Alias used inside the JVM. cnObTransportAlias : \"\" # -- Open banking AS transport truststore crt. This is normally generated from the OB issuing CA, OB Root CA and Signing CA. Used when .global.cnObExtSigningJwksUri is set. Used in SSA Validation. This must be encoded using base64. cnObTransportTrustStore : Please note that the password for the keystores created can be fetched by executing the following command: kubectl get secret cn -n gluu --template={{.data.auth_openid_jks_pass}} | base64 -d The above password is needed in custom scripts such as the Client Registration script After finishing all the tweaks to the override.yaml file, run helm install or helm upgrade if Gluu is already installed helm repo add gluu-flex https://docs.gluu.org/charts helm repo update helm install gluu gluu-flex/gluu -n gluu -f override.yaml Install on microK8s(development/testing) # sudo su - wget https://raw.githubusercontent.com/GluuFederation/flex/main/automation/startopenabankingdemo.sh && chmod u+x startopenabankingdemo.sh && ./startopenabankingdemo.sh Running this script will install the Gluu Open Banking Platform along with th mysql persistence. After running the script, you can go ahead and test the setup . Testing the setup # After successful installation, you can access and test the Gluu Open Banking Platform using either curl or Jans-CLI . Changing the signing key kid for the AS dynamically # Get a client id and its associated password. We will use the jans-config-api client id and secret TESTCLIENT = $( kubectl get cm cn -n gluu --template ={{ .data.jca_client_id }} ) TESTCLIENTSECRET = $( kubectl get secret cn -n gluu --template ={{ .data.jca_client_pw }} | base64 -d ) Get a token. To pass mTLS, we will use client.crt and client.key: curl -k -u $TESTCLIENT : $TESTCLIENTSECRET https:///jans-auth/restv1/token -d \"grant_type=client_credentials&scope=https://jans.io/oauth/jans-auth-server/config/properties.write\" --cert client.crt --key client.key Add the entry staticKid to force the AS to use a specific signing key. Please modify XhCYDfFM7UFXHfykNaLk1aLCnZM to the kid to be used: curl -k -X PATCH \"https:///jans-config-api/api/v1/jans-auth-server/config\" -H \"accept: application/json\" -H \"Content-Type: application/json-patch+json\" -H \"Authorization:Bearer 170e8412-1d55-4b19-ssss-8fcdeaafb954\" -d \"[{\\\"op\\\":\\\"add\\\",\\\"path\\\":\\\"/staticKid\\\",\\\"value\\\":\\\"XhCYDfFM7UFXHfykNaLk1aLCnZM\\\"}]\" Perform a rolling restart for the auth-server and config-api deployments. kubectl rollout restart deployment -auth-server -n gluu kubectl rollout restart deployment -config-api -n gluu Adding custom scopes upon installation # Download the original scopes file wget https://raw.githubusercontent.com/JanssenProject/docker-jans-persistence-loader/master/templates/scopes.ob.ldif Add to the file the custom scopes desired. Create a configmap with the scopes file kubectl create cm custom-scopes -n gluu --from-file=scopes.ob.ldif Mount the configmap in your override.yaml under persistence.volumes and persistence.volumeMounts persistence : volumes : - name : custom-scopes configMap : name : custom-scopes volumeMounts : - name : custom-scopes mountPath : \"/app/templates/scopes.ob.ldif\" subPath : scopes.ob.ldif Run helm install or helm upgrade if Gluu has already been installed.","title":"Cloud-Native"},{"location":"openbanking/install-cn/#system-requirements","text":"Use the listing below for a detailed estimation of the minimum required resources. The table contains the default resources recommendation per service. Depending on the use of each service the resources need may increase or decrease. Service CPU Unit RAM Disk Space Processor Type Required Auth-server 2.5 2.5GB N/A 64 Bit Yes config - job 0.5 0.5GB N/A 64 Bit Yes on fresh installs persistence - job 0.5 0.5GB N/A 64 Bit Yes on fresh installs nginx 1 1GB N/A 64 Bit Yes if not ALB or Istio config-api 1 1GB N/A 64 Bit No","title":"System Requirements"},{"location":"openbanking/install-cn/#installation","text":"","title":"Installation"},{"location":"openbanking/install-cn/#install-using-helmproduction-ready","text":"The below certificates and keys are needed to complete the installation. Certificate / key Description OB Issuing CA Used in nginx as a certificate authority OB Root CA Used in nginx as a certificate authority OB Signing CA Used in nginx as a certificate authority OB AS Transport key Used for mTLS. This will also be added to the JVM OB AS Transport crt Used for mTLS. This will also be added to the JVM OB AS signing crt Added to the JVM. Used in SSA Validation OB AS signing key Added to the JVM. Used in SSA Validation OB transport truststore Used in SSA Validation. Generated from OB Root CA nd Issuing CA Based on the provider/platform you're using, you can follow the docs to install your platform prerequistes, nginx-ingress, and the yaml changes needed in override.yaml based on the Gluu persistence choosed. To enable mTLS in ingress-nginx, add the following to your override.yaml : nginx-ingress : ingress : additionalAnnotations : nginx.ingress.kubernetes.io/auth-tls-verify-client : \"optional\" nginx.ingress.kubernetes.io/auth-tls-secret : \"gluu/tls-ob-ca-certificates\" nginx.ingress.kubernetes.io/auth-tls-verify-depth : \"1\" nginx.ingress.kubernetes.io/auth-tls-pass-certificate-to-upstream : \"true\" Adding these annotations will enable client certificate authentication . Enable authServerProtectedToken and authServerProtectedRegister : global auth-server : ingress : authServerProtectedToken : true authServerProtectedRegister : true Enable HTTPS During fresh installation, the config-job checks if SSL certificates and keys are mounted as files. If no mounted files are found, it attempts to download SSL certificates from the FQDN supplied. If the download is successful, an empty key file is generated. If no mounted or downloaded files are found, it generates self-signed SSL certificates, CA certificates, and keys. certificates and keys of interest in https Notes web_https.crt (nginx) web server certificate. This is commonly referred to as server.crt web_https.key (nginx) web server key. This is commonly referred to as server.key web_https.csr (nginx) web server certificate signing request. This is commonly referred to as server.csr web_https_ca.crt Certificate authority certificate that signed/signs the web server certificate. web_https_ca.key Certificate authority key that signed/signs the web server certificate. Create a secret containing the OB CA certificates (issuing, root, and signing CAs) and the OB AS transport crt. For more information read here . cat web_https_ca.crt issuingca.crt rootca.crt signingca.crt >> ca.crt kubectl create secret generic tls-ob-ca-certificates -n gluu --from-file = tls.crt = web_https.crt --from-file = tls.key = web_https.key --from-file = ca.crt = ca.crt If you have an existing helm deployment, those secrets can be retrieved and then create using the following commands: kubectl get secret cn -n gluu --template ={{ .data.ssl_ca_cert }} | base64 -d > ca.crt kubectl get secret cn -n gluu --template ={{ .data.ssl_cert }} | base64 -d > server.crt kubectl get secret cn -n gluu --template ={{ .data.ssl_key }} | base64 -d > server.key kubectl create secret generic ca-secret -n gluu --from-file = tls.crt = server.crt --from-file = tls.key = server.key --from-file = ca.crt = ca.crt Inject OBIE signed certs, keys and uri: When using OBIE signed certificates and keys, there are many objects that can be injected. The certificate signing pem file i.e obsigning.pem , the signing key i.e obsigning-oajsdij8927123.key , the certificate transport pem file i.e obtransport.pem , the transport key i.e obtransport-sdfe4234234.key , the transport truststore p12 i.e ob-transport-truststore.p12 , and the jwks uri https://mykeystore.openbanking.wow/xxxxx/xxxxx.jwks . base64 encrypt all .pem and .key files. cat obsigning.pem | base64 | tr -d '\\n' > obsigningbase64.pem cat obsigning-oajsdij8927123.key | base64 | tr -d '\\n' > obsigningbase64.key cat obtransport.pem | base64 | tr -d '\\n' > obtransportbase64.pem cat obtransport-sdfe4234234.key | base64 | tr -d '\\n' > obtransportbase64.key Generate your transport truststore or convert it to .p12 format. Please name it as ob-transport-truststore.p12 cat obissuingca.pem obrootca.pem obsigningca.pem > transport-truststore.crt keytool -importcert -file transport-truststore.crt -keystore ob-transport-truststore.p12 -alias obkeystore base64 encrypt the ob-transport-truststore.p12 cat ob-transport-truststore.p12 | base64 | tr -d '\\n' > obtransporttruststorebase64.pem Add the kid as the alias for the JKS used for the OB AS external signing crt. This is a kid value.Used in SSA Validation, kid used while encoding a JWT sent to token URL i.e XkwIzWy44xWSlcWnMiEc8iq9s2G. This kid value should exist inside the jwks uri endpoint. Add those values to override.yaml : global : # -- Open banking external signing jwks uri. Used in SSA Validation. cnObExtSigningJwksUri : \"\" # -- Open banking external signing jwks AS certificate authority string. Used in SSA Validation. This must be encoded using base64.. Used when `.global.cnObExtSigningJwksUri` is set. cnObExtSigningJwksCrt : # -- Open banking external signing jwks AS key string. Used in SSA Validation. This must be encoded using base64. Used when `.global.cnObExtSigningJwksUri` is set. cnObExtSigningJwksKey : # -- Open banking external signing jwks AS key passphrase to unlock provided key. This must be encoded using base64. Used when `.global.cnObExtSigningJwksUri` is set. cnObExtSigningJwksKeyPassPhrase : # -- Open banking external signing AS Alias. This is a kid value. Used in SSA Validation, kid used while encoding a JWT sent to token URL i.e. XkwIzWy44xWSlcWnMiEc8iq9s2G cnObExtSigningAlias : # -- Open banking signing AS kid to force the AS to use a specific signing key. i.e. Wy44xWSlcWnMiEc8iq9s2G cnObStaticSigningKeyKid : # -- Open banking AS transport crt. Used in SSA Validation. This must be encoded using base64. cnObTransportCrt : # -- Open banking AS transport key. Used in SSA Validation. This must be encoded using base64. cnObTransportKey : # -- Open banking AS transport key passphrase to unlock AS transport key. This must be encoded using base64. cnObTransportKeyPassPhrase : # -- Open banking transport Alias used inside the JVM. cnObTransportAlias : \"\" # -- Open banking AS transport truststore crt. This is normally generated from the OB issuing CA, OB Root CA and Signing CA. Used when .global.cnObExtSigningJwksUri is set. Used in SSA Validation. This must be encoded using base64. cnObTransportTrustStore : Please note that the password for the keystores created can be fetched by executing the following command: kubectl get secret cn -n gluu --template={{.data.auth_openid_jks_pass}} | base64 -d The above password is needed in custom scripts such as the Client Registration script After finishing all the tweaks to the override.yaml file, run helm install or helm upgrade if Gluu is already installed helm repo add gluu-flex https://docs.gluu.org/charts helm repo update helm install gluu gluu-flex/gluu -n gluu -f override.yaml","title":"Install using Helm(production-ready)"},{"location":"openbanking/install-cn/#install-on-microk8sdevelopmenttesting","text":"sudo su - wget https://raw.githubusercontent.com/GluuFederation/flex/main/automation/startopenabankingdemo.sh && chmod u+x startopenabankingdemo.sh && ./startopenabankingdemo.sh Running this script will install the Gluu Open Banking Platform along with th mysql persistence. After running the script, you can go ahead and test the setup .","title":"Install on microK8s(development/testing)"},{"location":"openbanking/install-cn/#testing-the-setup","text":"After successful installation, you can access and test the Gluu Open Banking Platform using either curl or Jans-CLI .","title":"Testing the setup"},{"location":"openbanking/install-cn/#changing-the-signing-key-kid-for-the-as-dynamically","text":"Get a client id and its associated password. We will use the jans-config-api client id and secret TESTCLIENT = $( kubectl get cm cn -n gluu --template ={{ .data.jca_client_id }} ) TESTCLIENTSECRET = $( kubectl get secret cn -n gluu --template ={{ .data.jca_client_pw }} | base64 -d ) Get a token. To pass mTLS, we will use client.crt and client.key: curl -k -u $TESTCLIENT : $TESTCLIENTSECRET https:///jans-auth/restv1/token -d \"grant_type=client_credentials&scope=https://jans.io/oauth/jans-auth-server/config/properties.write\" --cert client.crt --key client.key Add the entry staticKid to force the AS to use a specific signing key. Please modify XhCYDfFM7UFXHfykNaLk1aLCnZM to the kid to be used: curl -k -X PATCH \"https:///jans-config-api/api/v1/jans-auth-server/config\" -H \"accept: application/json\" -H \"Content-Type: application/json-patch+json\" -H \"Authorization:Bearer 170e8412-1d55-4b19-ssss-8fcdeaafb954\" -d \"[{\\\"op\\\":\\\"add\\\",\\\"path\\\":\\\"/staticKid\\\",\\\"value\\\":\\\"XhCYDfFM7UFXHfykNaLk1aLCnZM\\\"}]\" Perform a rolling restart for the auth-server and config-api deployments. kubectl rollout restart deployment -auth-server -n gluu kubectl rollout restart deployment -config-api -n gluu","title":"Changing the signing key kid for the AS dynamically"},{"location":"openbanking/install-cn/#adding-custom-scopes-upon-installation","text":"Download the original scopes file wget https://raw.githubusercontent.com/JanssenProject/docker-jans-persistence-loader/master/templates/scopes.ob.ldif Add to the file the custom scopes desired. Create a configmap with the scopes file kubectl create cm custom-scopes -n gluu --from-file=scopes.ob.ldif Mount the configmap in your override.yaml under persistence.volumes and persistence.volumeMounts persistence : volumes : - name : custom-scopes configMap : name : custom-scopes volumeMounts : - name : custom-scopes mountPath : \"/app/templates/scopes.ob.ldif\" subPath : scopes.ob.ldif Run helm install or helm upgrade if Gluu has already been installed.","title":"Adding custom scopes upon installation"},{"location":"openbanking/install-vm/","text":"VM Based Distribution # This section covers details on installing Gluu Openbanking Indentity Platform 1.0 in a VM. We recommend the Cloud Native Distribution for production environment. However, for development and testing VM distribution will be easier. VM Preparation # Prepare a VM with the following minimum specs: 4 GB RAM 2 GB swap space 2 CPU units 50 GB disk space The VM must have a static IP address and a resolvable hostname. A fully qualified domain name (FQDN) is required for production deployments. The Gluu Open Banking Identity Platform can be installed on main Linux distributions. Installation # Download the installer ( install.py ) wget https://raw.githubusercontent.com/JanssenProject/jans/main/jans-linux-setup/jans_setup/install.py Execute the installer: sudo python3 install.py --profile openbanking The installation script will install required tools, programs, packages and then it will prompt the user for setup instructions. Answer the following questions: Certificate Generation Setup # Prompt Description Enter IP Address The IP address for the VM. Use an IP address assigned to one of this server's network interfaces (usage of addresses assigned to loopback interfaces is not supported) Enter Hostname The hostname for the VM. Recommended to be a FQDN Enter your city or locality Used to generate X.509 certificates. Enter your state or province two letter code Used to generate X.509 certificates. Enter two letter Country Code Used to generate X.509 certificates. Enter Organization Name Used to generate X.509 certificates. Enter email address for support at your organization Used to generate X.509 certificates. Architecture Setup # Prompt Description Enter maximum RAM for applications in MB Maximum RAM Size in MB RDBM Type Backend type. Currently only MySQL is supported Use remote RDBM Select if connecting to an external MySQL server Enter Openbanking static kid The fallback key when key is not passed in requests (as required by Openbanking) Use external key If yes, link to an external Open Banking key file Before the last question installer process will display the selected choices and confirm to proceed. Prompt Description Proceed with these values [Y/n] Confirmation before setting up the services. Uninstalling Janssen Server # Execute the installation script with the -uninstall argument. MTLS Configuration # For MTLS, OBIE-issued (for openbanking UK) certificates and keys should be used. The following discussion assumes that the file ca.crt has a CA certificate and ca.key has a CA private key. Following command generates self-signed ca.crt and ca.key: openssl req -newkey rsa:2048 -nodes -keyform PEM -keyout ca.key -x509 -days 3650 -outform PEM -out ca.crt The following set of commands is an example of how to create the server\u2019s private key ( server.key ), Certificate Signing Request (CSR) ( server.csr ) and certificate ( server.crt) : openssl genrsa -out server.key 2048 openssl req -new -key server.key -out server.csr openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -set_serial 100 -days 365 -outform PEM -out server.crt Now, store the server key ( server.key ) and certificate ( server.crt ) file in some location (preferably inside /etc/certs ) and set its path in the apache .conf file ( /etc/apache2/sites-enabled/https_jans.conf ) with SSLCertificateFile and SSLCertificateKeyFile directives: SSLCertificateFile /etc/certs/bankgluu/server.crt SSLCertificateKeyFile /etc/certs/bankgluu/server.key The path of CA certificate file should be set to SSLCACertificateFile directive as: SSLCACertificateFile /etc/apache2/certs/matls.pem The following commands will create client\u2019s private key ( client.key ), CSR ( client.csr ) and certificate ( client.crt ): openssl genrsa -out client.key 2048 openssl req -new -key client.key -out client.csr openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key -set_serial 101 -days 365 -outform PEM -out client.crt The following command will create a client certification chain (private key, public certificate and ca certificate) into the file client.pem : cat client.key client.crt ca.crt >client.pem Use this pem file to create JWKs for the clients (if required). To create a JWK, you can use a free utility published at https://mkjwk.org . Or you can download the command-line tool from GitHub . There are numerous other online PEM-to-JWKS tools available like JWKConvertFunctions . We may need to add/update some data in these generated JWKs. Note It is important to give different values of the Common Name field (\u201cCommon Name (e.g. server FQDN or YOUR name) []\u201d) for the CA, Server and clients. Other fields may have common values but the same values for Common Name of all certificates result in certificate verification failing at runtime. Importing the CA certificate in JVM truststore and signing, encryption keys into auth-Server keystore: # The command line utility keytool is installed with JDK, it can be used to import the CA certificate in JVM truststore (/opt/jre/lib/security/cacerts) and signing,encryption keys into the jans-auth server\u2019s keystore(/etc/certs/jans-auth-keys.jks). ./keytool -importcert -file /path/to/file/filename.cer -keystore /etc/certs/jans-auth-keys.jks -alias yourkeystore ./keytool -importkeystore -srckeystore /path/to/file/filename.jks -srcstoretype JKS -destkeystore /opt/jre/lib/security/cacerts -deststoretype JKS Accessing the Platform # After successful installation, access the Gluu Open Banking Platform using either jans-cli or curl .","title":"VM (only recommended for development/testing)"},{"location":"openbanking/install-vm/#vm-based-distribution","text":"This section covers details on installing Gluu Openbanking Indentity Platform 1.0 in a VM. We recommend the Cloud Native Distribution for production environment. However, for development and testing VM distribution will be easier.","title":"VM Based Distribution"},{"location":"openbanking/install-vm/#vm-preparation","text":"Prepare a VM with the following minimum specs: 4 GB RAM 2 GB swap space 2 CPU units 50 GB disk space The VM must have a static IP address and a resolvable hostname. A fully qualified domain name (FQDN) is required for production deployments. The Gluu Open Banking Identity Platform can be installed on main Linux distributions.","title":"VM Preparation"},{"location":"openbanking/install-vm/#installation","text":"Download the installer ( install.py ) wget https://raw.githubusercontent.com/JanssenProject/jans/main/jans-linux-setup/jans_setup/install.py Execute the installer: sudo python3 install.py --profile openbanking The installation script will install required tools, programs, packages and then it will prompt the user for setup instructions. Answer the following questions:","title":"Installation"},{"location":"openbanking/install-vm/#certificate-generation-setup","text":"Prompt Description Enter IP Address The IP address for the VM. Use an IP address assigned to one of this server's network interfaces (usage of addresses assigned to loopback interfaces is not supported) Enter Hostname The hostname for the VM. Recommended to be a FQDN Enter your city or locality Used to generate X.509 certificates. Enter your state or province two letter code Used to generate X.509 certificates. Enter two letter Country Code Used to generate X.509 certificates. Enter Organization Name Used to generate X.509 certificates. Enter email address for support at your organization Used to generate X.509 certificates.","title":"Certificate Generation Setup"},{"location":"openbanking/install-vm/#architecture-setup","text":"Prompt Description Enter maximum RAM for applications in MB Maximum RAM Size in MB RDBM Type Backend type. Currently only MySQL is supported Use remote RDBM Select if connecting to an external MySQL server Enter Openbanking static kid The fallback key when key is not passed in requests (as required by Openbanking) Use external key If yes, link to an external Open Banking key file Before the last question installer process will display the selected choices and confirm to proceed. Prompt Description Proceed with these values [Y/n] Confirmation before setting up the services.","title":"Architecture Setup"},{"location":"openbanking/install-vm/#uninstalling-janssen-server","text":"Execute the installation script with the -uninstall argument.","title":"Uninstalling Janssen Server"},{"location":"openbanking/install-vm/#mtls-configuration","text":"For MTLS, OBIE-issued (for openbanking UK) certificates and keys should be used. The following discussion assumes that the file ca.crt has a CA certificate and ca.key has a CA private key. Following command generates self-signed ca.crt and ca.key: openssl req -newkey rsa:2048 -nodes -keyform PEM -keyout ca.key -x509 -days 3650 -outform PEM -out ca.crt The following set of commands is an example of how to create the server\u2019s private key ( server.key ), Certificate Signing Request (CSR) ( server.csr ) and certificate ( server.crt) : openssl genrsa -out server.key 2048 openssl req -new -key server.key -out server.csr openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -set_serial 100 -days 365 -outform PEM -out server.crt Now, store the server key ( server.key ) and certificate ( server.crt ) file in some location (preferably inside /etc/certs ) and set its path in the apache .conf file ( /etc/apache2/sites-enabled/https_jans.conf ) with SSLCertificateFile and SSLCertificateKeyFile directives: SSLCertificateFile /etc/certs/bankgluu/server.crt SSLCertificateKeyFile /etc/certs/bankgluu/server.key The path of CA certificate file should be set to SSLCACertificateFile directive as: SSLCACertificateFile /etc/apache2/certs/matls.pem The following commands will create client\u2019s private key ( client.key ), CSR ( client.csr ) and certificate ( client.crt ): openssl genrsa -out client.key 2048 openssl req -new -key client.key -out client.csr openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key -set_serial 101 -days 365 -outform PEM -out client.crt The following command will create a client certification chain (private key, public certificate and ca certificate) into the file client.pem : cat client.key client.crt ca.crt >client.pem Use this pem file to create JWKs for the clients (if required). To create a JWK, you can use a free utility published at https://mkjwk.org . Or you can download the command-line tool from GitHub . There are numerous other online PEM-to-JWKS tools available like JWKConvertFunctions . We may need to add/update some data in these generated JWKs. Note It is important to give different values of the Common Name field (\u201cCommon Name (e.g. server FQDN or YOUR name) []\u201d) for the CA, Server and clients. Other fields may have common values but the same values for Common Name of all certificates result in certificate verification failing at runtime.","title":"MTLS Configuration"},{"location":"openbanking/install-vm/#importing-the-ca-certificate-in-jvm-truststore-and-signing-encryption-keys-into-auth-server-keystore","text":"The command line utility keytool is installed with JDK, it can be used to import the CA certificate in JVM truststore (/opt/jre/lib/security/cacerts) and signing,encryption keys into the jans-auth server\u2019s keystore(/etc/certs/jans-auth-keys.jks). ./keytool -importcert -file /path/to/file/filename.cer -keystore /etc/certs/jans-auth-keys.jks -alias yourkeystore ./keytool -importkeystore -srckeystore /path/to/file/filename.jks -srcstoretype JKS -destkeystore /opt/jre/lib/security/cacerts -deststoretype JKS","title":"Importing the CA certificate in JVM truststore and signing, encryption keys into auth-Server keystore:"},{"location":"openbanking/install-vm/#accessing-the-platform","text":"After successful installation, access the Gluu Open Banking Platform using either jans-cli or curl .","title":"Accessing the Platform"},{"location":"openbanking/jans-cli/","text":"Introduction # Jans-cli is a command line interface to configure the Janssen software and it supports both interactive and command-line options for configuration. Jans-cli calls the Jans-Config-API to perform various operations. During Janssen installation, the installer creates a client to use Jans Config API. Jans-cli uses this client to call Jans Config API. Supported Operations # Jans-cli supports the following six operations on custom scripts: get-config-scripts : gets a list of custom scripts. post-config-scripts : adds a new custom script. put-config-scripts : updates a custom script. get-config-scripts-by-type : requires an argument --url-suffix TYPE: <> . You can specify the following types: PERSON_AUTHENTICATION , INTROSPECTION , RESOURCE_OWNER_PASSWORD_CREDENTIALS , APPLICATION_SESSION , CACHE_REFRESH , UPDATE_USER , USER_REGISTRATION , CLIENT_REGISTRATION , ID_GENERATOR , UMA_RPT_POLICY , UMA_RPT_CLAIMS , UMA_CLAIMS_GATHERING , CONSENT_GATHERING , DYNAMIC_SCOPE , SPONTANEOUS_SCOPE , END_SESSION , POST_AUTHN , SCIM , CIBA_END_USER_NOTIFICATION , PERSISTENCE_EXTENSION , IDP , or UPDATE_TOKEN . get-config-scripts-by-inum : requires an argument --url-suffix inum: <> delete-config-scripts-by-inum : requires an argument --url-suffix inum: <> Using jans-cli # Download jans-cli.pyz . This package can be built manually too. Get a client id and its associated password. Here, we will use the client id and secret created for config-api. TESTCLIENT = $( kubectl get cm cn -n --template ={{ .data.jca_client_id }} ) TESTCLIENTSECRET = $( kubectl get secret cn -n --template ={{ .data.jca_client_pw }} | base64 -d ) client.crt and client.key are the certificate and key files respectively for MTLS. We need to pass this certificate, key as the token endpoint is under MTLS and jans-cli obtains an appropriate token before performing the operation. Use your ca.crt and ca.key that was provided during setup to generate as many client certificates and keys for operating jans-cli as needed. If you have an existing helm deployment, you can retrieve ca.crt and ca.key using the following commands: kubectl get secret cn -n --template ={{ .data.ssl_ca_cert }} | base64 -d > ca.crt kubectl get secret cn -n --template ={{ .data.ssl_ca_key }} | base64 -d > ca.key Generate client.crt and client.key files: openssl req -new -newkey rsa:4096 -keyout client.key -out client.csr -nodes -subj '/CN=Openbanking' openssl x509 -req -sha256 -days 365 -in client.csr -CA ca.crt -CAkey ca.key -set_serial 02 -out client.crt Run the jans-cli in interactive mode and try it out: python3 jans-cli-linux-amd64.pyz --host --client-id $TESTCLIENT --client_secret $TESTCLIENTSECRET --CC client.crt --CK client.key Examples # The post-config-scripts and put-config-scripts require various details about the scripts. The following command gives the basic schema of the custom scripts to pass to these operations. python3 jans-cli-linux-amd64.pyz --host --client-id $TESTCLIENT --client_secret $TESTCLIENTSECRET --schema /components/schemas/CustomScript The output of the above command will be similar as: { \"dn\" : null , \"inum\" : null , \"name\" : \"string\" , \"aliases\" : [], \"description\" : null , \"script\" : \"string\" , \"scriptType\" : \"IDP\" , \"programmingLanguage\" : \"PYTHON\" , \"moduleProperties\" : { \"value1\" : null , \"value2\" : null , \"description\" : null }, \"configurationProperties\" : { \"value1\" : null , \"value2\" : null , \"description\" : null , \"hide\" : true }, \"level\" : \"integer\" , \"revision\" : 0 , \"enabled\" : false , \"scriptError\" : { \"raisedAt\" : null , \"stackTrace\" : null }, \"modified\" : false , \"internal\" : false } To add or modify a script first, we need to create the script's python file (e.g. /tmp/sample.py) and then create a JSON file by following the above schema and update the fields as : /tmp/sample.json { \"name\" : \"mySampleScript\" , \"aliases\" : null , \"description\" : \"This is a sample script\" , \"script\" : \"_file /tmp/sample.py\" , \"scriptType\" : \"PERSON_AUTHENTICATION\" , \"programmingLanguage\" : \"PYTHON\" , \"moduleProperties\" : [ { \"value1\" : \"mayvalue1\" , \"value2\" : \"myvalues2\" , \"description\" : \"description for property\" } ], \"configurationProperties\" : null , \"level\" : 1 , \"revision\" : 0 , \"enabled\" : false , \"scriptError\" : null , \"modified\" : false , \"internal\" : false } Add a new custom script, update and delete existing custom script # The following command will add a new script with details given in /tmp/sampleadd.json file. The jans-cli will generate a unique inum of this new script if we skip inum in the json file. python3 jans-cli-linux-amd64.pyz --host --client-id $TESTCLIENT --client_secret $TESTCLIENTSECRET --operation-id post-config-scripts --data /tmp/sampleadd.json \\ --CC client.crt --CK client.key The following command will modify/update the existing script with details given in /tmp/samplemodify.json file. Remember to set inum field in samplemodify.json to the inum of the script to update. python3 jans-cli-linux-amd64.pyz --host --client-id $TESTCLIENT --client_secret $TESTCLIENTSECRET --operation-id put-config-scripts --data /tmp/samplemodify.json \\ --CC client.crt --CK client.key To delete a custom script by its inum, use the following command: python3 jans-cli-linux-amd64.pyz --host --client-id $TESTCLIENT --client_secret $TESTCLIENTSECRET --operation-id delete-config-scripts-by-inum --url-suffix inum:HKM-TEST \\ --CC client.crt --CK client.key Print details of existing custom scripts # These commands to print the details are important, as using them we can get the inum of these scripts which is required to perform update or delete operations. The following command will display the details of all the existing custom scripts. This will be helpful to get the inum of scripts to perform the update and delete operation. python3 jans-cli-linux-amd64.pyz --host --client-id $TESTCLIENT --client_secret $TESTCLIENTSECRET --operation-id get-config-scripts --CC client.crt --CK client.key The following command displays the details of selected custom script (by inum). python3 jans-cli-linux-amd64.pyz --host --client-id $TESTCLIENT --client_secret $TESTCLIENTSECRET --operation-id get-config-scripts-by-inum --url-suffix inum:_____ \\ --CC client.crt --CK client.key Use the following command to display the details of existing custom scripts of a given type (for example: INTROSPECTION). python3 jans-cli-linux-amd64.pyz --host --client-id $TESTCLIENT --client_secret $TESTCLIENTSECRET --operation-id get-config-scripts-by-type --url-suffix type:INTROSPECTION \\ --CC client.crt --CK client.key","title":"Managing Scripts with the jans-cli"},{"location":"openbanking/jans-cli/#introduction","text":"Jans-cli is a command line interface to configure the Janssen software and it supports both interactive and command-line options for configuration. Jans-cli calls the Jans-Config-API to perform various operations. During Janssen installation, the installer creates a client to use Jans Config API. Jans-cli uses this client to call Jans Config API.","title":"Introduction"},{"location":"openbanking/jans-cli/#supported-operations","text":"Jans-cli supports the following six operations on custom scripts: get-config-scripts : gets a list of custom scripts. post-config-scripts : adds a new custom script. put-config-scripts : updates a custom script. get-config-scripts-by-type : requires an argument --url-suffix TYPE: <> . You can specify the following types: PERSON_AUTHENTICATION , INTROSPECTION , RESOURCE_OWNER_PASSWORD_CREDENTIALS , APPLICATION_SESSION , CACHE_REFRESH , UPDATE_USER , USER_REGISTRATION , CLIENT_REGISTRATION , ID_GENERATOR , UMA_RPT_POLICY , UMA_RPT_CLAIMS , UMA_CLAIMS_GATHERING , CONSENT_GATHERING , DYNAMIC_SCOPE , SPONTANEOUS_SCOPE , END_SESSION , POST_AUTHN , SCIM , CIBA_END_USER_NOTIFICATION , PERSISTENCE_EXTENSION , IDP , or UPDATE_TOKEN . get-config-scripts-by-inum : requires an argument --url-suffix inum: <> delete-config-scripts-by-inum : requires an argument --url-suffix inum: <>","title":"Supported Operations"},{"location":"openbanking/jans-cli/#using-jans-cli","text":"Download jans-cli.pyz . This package can be built manually too. Get a client id and its associated password. Here, we will use the client id and secret created for config-api. TESTCLIENT = $( kubectl get cm cn -n --template ={{ .data.jca_client_id }} ) TESTCLIENTSECRET = $( kubectl get secret cn -n --template ={{ .data.jca_client_pw }} | base64 -d ) client.crt and client.key are the certificate and key files respectively for MTLS. We need to pass this certificate, key as the token endpoint is under MTLS and jans-cli obtains an appropriate token before performing the operation. Use your ca.crt and ca.key that was provided during setup to generate as many client certificates and keys for operating jans-cli as needed. If you have an existing helm deployment, you can retrieve ca.crt and ca.key using the following commands: kubectl get secret cn -n --template ={{ .data.ssl_ca_cert }} | base64 -d > ca.crt kubectl get secret cn -n --template ={{ .data.ssl_ca_key }} | base64 -d > ca.key Generate client.crt and client.key files: openssl req -new -newkey rsa:4096 -keyout client.key -out client.csr -nodes -subj '/CN=Openbanking' openssl x509 -req -sha256 -days 365 -in client.csr -CA ca.crt -CAkey ca.key -set_serial 02 -out client.crt Run the jans-cli in interactive mode and try it out: python3 jans-cli-linux-amd64.pyz --host --client-id $TESTCLIENT --client_secret $TESTCLIENTSECRET --CC client.crt --CK client.key","title":"Using jans-cli"},{"location":"openbanking/jans-cli/#examples","text":"The post-config-scripts and put-config-scripts require various details about the scripts. The following command gives the basic schema of the custom scripts to pass to these operations. python3 jans-cli-linux-amd64.pyz --host --client-id $TESTCLIENT --client_secret $TESTCLIENTSECRET --schema /components/schemas/CustomScript The output of the above command will be similar as: { \"dn\" : null , \"inum\" : null , \"name\" : \"string\" , \"aliases\" : [], \"description\" : null , \"script\" : \"string\" , \"scriptType\" : \"IDP\" , \"programmingLanguage\" : \"PYTHON\" , \"moduleProperties\" : { \"value1\" : null , \"value2\" : null , \"description\" : null }, \"configurationProperties\" : { \"value1\" : null , \"value2\" : null , \"description\" : null , \"hide\" : true }, \"level\" : \"integer\" , \"revision\" : 0 , \"enabled\" : false , \"scriptError\" : { \"raisedAt\" : null , \"stackTrace\" : null }, \"modified\" : false , \"internal\" : false } To add or modify a script first, we need to create the script's python file (e.g. /tmp/sample.py) and then create a JSON file by following the above schema and update the fields as : /tmp/sample.json { \"name\" : \"mySampleScript\" , \"aliases\" : null , \"description\" : \"This is a sample script\" , \"script\" : \"_file /tmp/sample.py\" , \"scriptType\" : \"PERSON_AUTHENTICATION\" , \"programmingLanguage\" : \"PYTHON\" , \"moduleProperties\" : [ { \"value1\" : \"mayvalue1\" , \"value2\" : \"myvalues2\" , \"description\" : \"description for property\" } ], \"configurationProperties\" : null , \"level\" : 1 , \"revision\" : 0 , \"enabled\" : false , \"scriptError\" : null , \"modified\" : false , \"internal\" : false }","title":"Examples"},{"location":"openbanking/jans-cli/#add-a-new-custom-script-update-and-delete-existing-custom-script","text":"The following command will add a new script with details given in /tmp/sampleadd.json file. The jans-cli will generate a unique inum of this new script if we skip inum in the json file. python3 jans-cli-linux-amd64.pyz --host --client-id $TESTCLIENT --client_secret $TESTCLIENTSECRET --operation-id post-config-scripts --data /tmp/sampleadd.json \\ --CC client.crt --CK client.key The following command will modify/update the existing script with details given in /tmp/samplemodify.json file. Remember to set inum field in samplemodify.json to the inum of the script to update. python3 jans-cli-linux-amd64.pyz --host --client-id $TESTCLIENT --client_secret $TESTCLIENTSECRET --operation-id put-config-scripts --data /tmp/samplemodify.json \\ --CC client.crt --CK client.key To delete a custom script by its inum, use the following command: python3 jans-cli-linux-amd64.pyz --host --client-id $TESTCLIENT --client_secret $TESTCLIENTSECRET --operation-id delete-config-scripts-by-inum --url-suffix inum:HKM-TEST \\ --CC client.crt --CK client.key","title":"Add a new custom script, update and delete existing custom script"},{"location":"openbanking/jans-cli/#print-details-of-existing-custom-scripts","text":"These commands to print the details are important, as using them we can get the inum of these scripts which is required to perform update or delete operations. The following command will display the details of all the existing custom scripts. This will be helpful to get the inum of scripts to perform the update and delete operation. python3 jans-cli-linux-amd64.pyz --host --client-id $TESTCLIENT --client_secret $TESTCLIENTSECRET --operation-id get-config-scripts --CC client.crt --CK client.key The following command displays the details of selected custom script (by inum). python3 jans-cli-linux-amd64.pyz --host --client-id $TESTCLIENT --client_secret $TESTCLIENTSECRET --operation-id get-config-scripts-by-inum --url-suffix inum:_____ \\ --CC client.crt --CK client.key Use the following command to display the details of existing custom scripts of a given type (for example: INTROSPECTION). python3 jans-cli-linux-amd64.pyz --host --client-id $TESTCLIENT --client_secret $TESTCLIENTSECRET --operation-id get-config-scripts-by-type --url-suffix type:INTROSPECTION \\ --CC client.crt --CK client.key","title":"Print details of existing custom scripts"},{"location":"openbanking/par-jarm/","text":"Pushed Authorization Requests(PAR) and JWT Secured Authorization Response Mode(JARM) # This section covers details of two important features required by the open banking ecosystem. The latest Gluu Open Banking Identity Platform supports PAR and JARM specifications. These two features are bundled in the installation so when you install the Gluu Open Banking Identity Platform the Authorization Server(AS) will support these features by default. The older/existing installation may require updating the WAR/ image. Moreover, these features are also FAPI certified for Brazil Open Banking (Based on FAPI 1 Advanced Final) . Pushed Authorization Requests-PAR: # PAR are handled by an additional endpoint of Authorization Server (AS). Clients POST their authorization parameters to this endpoint, in return the clients gets a reference (named as request URI value) that will be used in further authorization requests by the client. PAR enables the OAuth clients to push the payload of an authorization request directly to the authorization server in exchange for a request URI value. This request URI value is used as a reference to the authorization request payload data in a subsequent call to the authorization endpoint. We can set different PAR lifetimes for different clients . PAR lifetime will be 600 seconds if it is unspecified . We have two new configuration properties for PAR: * parEndpoint - String , corresponds to pushed_authorization_request_endpoint as defined by specification . * requirePar - Boolean parameter indicating whether the only means of initiating an authorization request the client is allowed to use is a pushed authorization request . If omitted , the default value is \"false\" . Moreover, there is a new client configuration: * parLifetime: An integer parameter representing the lifetime (in seconds) of the pushed authorization request. JWT Secured Authorization Response Mode-JARM # This is a new JWT-based response mode to encode authorization responses known as JARM, (see Financial-grade API: JWT Secured Authorization Response Mode for OAuth 2.0 ). Here clients are enabled to request the transmission of the authorization response parameters along with additional data in JWT format. This mechanism enhances the security of the standard authorization response since it adds support for signing and encryption,sender authentication, and audience restriction. It also provides protection from replay, credential leakage, and mix-up attacks. It can be combined with any response type. For this feature AS supports new response modes ( query.jwt , fragment.jwt , form_post.jwt , jwt ) and additional signing, encryption algorithms.","title":"PAR and JARM"},{"location":"openbanking/par-jarm/#pushed-authorization-requestspar-and-jwt-secured-authorization-response-modejarm","text":"This section covers details of two important features required by the open banking ecosystem. The latest Gluu Open Banking Identity Platform supports PAR and JARM specifications. These two features are bundled in the installation so when you install the Gluu Open Banking Identity Platform the Authorization Server(AS) will support these features by default. The older/existing installation may require updating the WAR/ image. Moreover, these features are also FAPI certified for Brazil Open Banking (Based on FAPI 1 Advanced Final) .","title":"Pushed Authorization Requests(PAR) and JWT Secured Authorization Response Mode(JARM)"},{"location":"openbanking/par-jarm/#pushed-authorization-requests-par","text":"PAR are handled by an additional endpoint of Authorization Server (AS). Clients POST their authorization parameters to this endpoint, in return the clients gets a reference (named as request URI value) that will be used in further authorization requests by the client. PAR enables the OAuth clients to push the payload of an authorization request directly to the authorization server in exchange for a request URI value. This request URI value is used as a reference to the authorization request payload data in a subsequent call to the authorization endpoint. We can set different PAR lifetimes for different clients . PAR lifetime will be 600 seconds if it is unspecified . We have two new configuration properties for PAR: * parEndpoint - String , corresponds to pushed_authorization_request_endpoint as defined by specification . * requirePar - Boolean parameter indicating whether the only means of initiating an authorization request the client is allowed to use is a pushed authorization request . If omitted , the default value is \"false\" . Moreover, there is a new client configuration: * parLifetime: An integer parameter representing the lifetime (in seconds) of the pushed authorization request.","title":"Pushed Authorization Requests-PAR:"},{"location":"openbanking/par-jarm/#jwt-secured-authorization-response-mode-jarm","text":"This is a new JWT-based response mode to encode authorization responses known as JARM, (see Financial-grade API: JWT Secured Authorization Response Mode for OAuth 2.0 ). Here clients are enabled to request the transmission of the authorization response parameters along with additional data in JWT format. This mechanism enhances the security of the standard authorization response since it adds support for signing and encryption,sender authentication, and audience restriction. It also provides protection from replay, credential leakage, and mix-up attacks. It can be combined with any response type. For this feature AS supports new response modes ( query.jwt , fragment.jwt , form_post.jwt , jwt ) and additional signing, encryption algorithms.","title":"JWT Secured Authorization Response Mode-JARM"},{"location":"reference/","tags":["administration","reference"],"text":"Overview # The Gluu Flex reference guide includes technical references for Flex-specific components and deployments. References for Janssen components, including database references, can be found in the Janssen Project documentation .","title":"Overview"},{"location":"reference/#overview","text":"The Gluu Flex reference guide includes technical references for Flex-specific components and deployments. References for Janssen components, including database references, can be found in the Janssen Project documentation .","title":"Overview"},{"location":"reference/json-config/","text":"Where is this content? # The Gluu Flex documentation is a work in progress, and this document is currently a draft. Keep an eye on this page for updates.","title":"Index"},{"location":"reference/json-config/#where-is-this-content","text":"The Gluu Flex documentation is a work in progress, and this document is currently a draft. Keep an eye on this page for updates.","title":"Where is this content?"},{"location":"reference/json-config/properties/","text":"Where is this content? # The Gluu Flex documentation is a work in progress, and this document is currently a draft. Keep an eye on this page for updates.","title":"Index"},{"location":"reference/json-config/properties/#where-is-this-content","text":"The Gluu Flex documentation is a work in progress, and this document is currently a draft. Keep an eye on this page for updates.","title":"Where is this content?"},{"location":"reference/json-config/properties/casa-properties/","text":"Where is this content? # The Gluu Flex documentation is a work in progress, and this document is currently a draft. Keep an eye on this page for updates.","title":"Casa properties"},{"location":"reference/json-config/properties/casa-properties/#where-is-this-content","text":"The Gluu Flex documentation is a work in progress, and this document is currently a draft. Keep an eye on this page for updates.","title":"Where is this content?"},{"location":"reference/json-config/properties/casaconfig-properties/","text":"Where is this content? # The Gluu Flex documentation is a work in progress, and this document is currently a draft. Keep an eye on this page for updates.","title":"Casaconfig properties"},{"location":"reference/json-config/properties/casaconfig-properties/#where-is-this-content","text":"The Gluu Flex documentation is a work in progress, and this document is currently a draft. Keep an eye on this page for updates.","title":"Where is this content?"},{"location":"reference/kubernetes/","tags":["administration","reference","kubernetes","architecture","components"],"text":"Overview # This Reference guide helps you learn about the components and architecture of Gluu Flex. Gluu Flex components # auth-server : The OAuth Authorization Server, the OpenID Connect Provider, the UMA Authorization Server--this is the main Internet facing component of Janssen. It's the service that returns tokens, JWT's and identity assertions. This service must be Internet facing. auth-key-rotation : Responsible for regenerating auth-keys per x hours. config-api : The API to configure the auth-server and other components is consolidated in this component. This service should not be Internet-facing. Fido : Provides the server side endpoints to enroll and validate devices that use FIDO. It provides both FIDO U2F (register, authenticate) and FIDO 2 (attestation, assertion) endpoints. This service must be internet facing. SCIM : a JSON/REST API to manage user data. Use it to add, edit and update user information. This service should not be Internet facing. Casa : self-service web portal for end-users to manage authentication and authorization preferences for their account in a Gluu Server. Admin UI : The admin web portal to configure and control your Gluu server. Architectural diagram of Gluu #","title":"Overview"},{"location":"reference/kubernetes/#overview","text":"This Reference guide helps you learn about the components and architecture of Gluu Flex.","title":"Overview"},{"location":"reference/kubernetes/#gluu-flex-components","text":"auth-server : The OAuth Authorization Server, the OpenID Connect Provider, the UMA Authorization Server--this is the main Internet facing component of Janssen. It's the service that returns tokens, JWT's and identity assertions. This service must be Internet facing. auth-key-rotation : Responsible for regenerating auth-keys per x hours. config-api : The API to configure the auth-server and other components is consolidated in this component. This service should not be Internet-facing. Fido : Provides the server side endpoints to enroll and validate devices that use FIDO. It provides both FIDO U2F (register, authenticate) and FIDO 2 (attestation, assertion) endpoints. This service must be internet facing. SCIM : a JSON/REST API to manage user data. Use it to add, edit and update user information. This service should not be Internet facing. Casa : self-service web portal for end-users to manage authentication and authorization preferences for their account in a Gluu Server. Admin UI : The admin web portal to configure and control your Gluu server.","title":"Gluu Flex components"},{"location":"reference/kubernetes/#architectural-diagram-of-gluu","text":"","title":"Architectural diagram of Gluu"},{"location":"reference/kubernetes/docker-admin-ui/","tags":["administration","reference","kubernetes","docker image"],"text":"docker-admin-ui # A containerized application for Gluu Admin UI frontend. Versions # See Releases for stable versions. For bleeding-edge/unstable version, use gluufederation/admin-ui:1.0.0_dev . Environment Variables # The following environment variables are supported by the container: CN_CONFIG_ADAPTER : The config backend adapter, can be consul (default), kubernetes , or google . CN_CONFIG_CONSUL_HOST : hostname or IP of Consul (default to localhost ). CN_CONFIG_CONSUL_PORT : port of Consul (default to 8500 ). CN_CONFIG_CONSUL_CONSISTENCY : Consul consistency mode (choose one of default , consistent , or stale ). Default to stale mode. CN_CONFIG_CONSUL_SCHEME : supported Consul scheme ( http or https ). CN_CONFIG_CONSUL_VERIFY : whether to verify cert or not (default to false ). CN_CONFIG_CONSUL_CACERT_FILE : path to Consul CA cert file (default to /etc/certs/consul_ca.crt ). This file will be used if it exists and CN_CONFIG_CONSUL_VERIFY set to true . CN_CONFIG_CONSUL_CERT_FILE : path to Consul cert file (default to /etc/certs/consul_client.crt ). CN_CONFIG_CONSUL_KEY_FILE : path to Consul key file (default to /etc/certs/consul_client.key ). CN_CONFIG_CONSUL_TOKEN_FILE : path to file contains ACL token (default to /etc/certs/consul_token ). CN_CONFIG_KUBERNETES_NAMESPACE : Kubernetes namespace (default to default ). CN_CONFIG_KUBERNETES_CONFIGMAP : Kubernetes configmaps name (default to jans ). CN_CONFIG_KUBERNETES_USE_KUBE_CONFIG : Load credentials from $HOME/.kube/config , only useful for non-container environment (default to false ). CN_SECRET_ADAPTER : The secrets' adapter, can be vault (default), kubernetes , or google . CN_SECRET_VAULT_VERIFY : whether to verify cert or not (default to false ). CN_SECRET_VAULT_ROLE_ID_FILE : path to file contains Vault AppRole role ID (default to /etc/certs/vault_role_id ). CN_SECRET_VAULT_SECRET_ID_FILE : path to file contains Vault AppRole secret ID (default to /etc/certs/vault_secret_id ). CN_SECRET_VAULT_CERT_FILE : path to Vault cert file (default to /etc/certs/vault_client.crt ). CN_SECRET_VAULT_KEY_FILE : path to Vault key file (default to /etc/certs/vault_client.key ). CN_SECRET_VAULT_CACERT_FILE : path to Vault CA cert file (default to /etc/certs/vault_ca.crt ). This file will be used if it exists and CN_SECRET_VAULT_VERIFY set to true . CN_SECRET_VAULT_ADDR : URL of Vault (default to http://localhost:8200 ). CN_SECRET_VAULT_NAMESPACE : Namespace used to access secrets (default to empty string). CN_SECRET_VAULT_KV_PATH : Path to KV secrets engine (default to secret ). CN_SECRET_VAULT_PREFIX : Base prefix name used to build secret path (default to jans ). CN_SECRET_VAULT_APPROLE_PATH : Path to AppRole (default to approle ). CN_SECRET_KUBERNETES_NAMESPACE : Kubernetes namespace (default to default ). CN_SECRET_KUBERNETES_CONFIGMAP : Kubernetes secrets name (default to jans ). CN_SECRET_KUBERNETES_USE_KUBE_CONFIG : Load credentials from $HOME/.kube/config , only useful for non-container environment (default to false ). CN_WAIT_MAX_TIME : How long the startup \"health checks\" should run (default to 300 seconds). CN_WAIT_SLEEP_DURATION : Delay between startup \"health checks\" (default to 10 seconds). GOOGLE_PROJECT_ID : Google Project ID (default to empty string). Used when CN_CONFIG_ADAPTER or CN_SECRET_ADAPTER set to google . GOOGLE_APPLICATION_CREDENTIALS : Optional JSON file (contains Google credentials) that can be injected into container for authentication. Refer to https://cloud.google.com/docs/authentication/provide-credentials-adc#how-to for supported credentials. CN_GOOGLE_SECRET_VERSION_ID : Janssen secret version ID in Google Secret Manager. Defaults to latest , which is recommended. CN_GOOGLE_SECRET_NAME_PREFIX : Prefix for Janssen secret in Google Secret Manager. Defaults to jans . If left jans-secret secret will be created. CN_GOOGLE_SECRET_MANAGER_PASSPHRASE : Passphrase for Janssen secret in Google Secret Manager. This is recommended to be changed and defaults to secret . CN_AUTH_BASE_URL : Base URL of auth server (default to empty). CN_CONFIG_API_BASE_URL : Base URL of config-api server (default to empty). CN_TOKEN_SERVER_BASE_URL : Base URL of token server (default to empty). CN_TOKEN_SERVER_AUTHZ_ENDPOINT : Authorization endpoint at token server (default to /jans-auth/authorize.htm ). CN_TOKEN_SERVER_TOKEN_ENDPOINT : Token endpoint at token server (default to /jans-auth/restv1/token ). CN_TOKEN_SERVER_INTROSPECTION_ENDPOINT : Introspection endpoint at token server (default to /jans-auth/restv1/introspection ). CN_TOKEN_SERVER_USERINFO_ENDPOINT : User info endpoint at token server (default to /jans-auth/restv1/userinfo ). CN_TOKEN_SERVER_CLIENT_ID : Client ID registered at token server. CN_TOKEN_SERVER_CERT_FILE : Path to token server certificate (default to /etc/certs/token_server.crt ). CN_PERSISTENCE_TYPE : Persistence backend being used (one of sql , spanner , couchbase , or hybrid ; default to sql ). CN_HYBRID_MAPPING : Specify data mapping for each persistence (default to \"{}\" ). Note this environment only takes effect when CN_PERSISTENCE_TYPE is set to hybrid . See hybrid mapping section for details. CN_COUCHBASE_URL : Address of Couchbase server (default to localhost ). CN_COUCHBASE_USER : Username of Couchbase server (default to admin ). CN_COUCHBASE_CERT_FILE : Couchbase root certificate location (default to /etc/certs/couchbase.crt ). CN_COUCHBASE_PASSWORD_FILE : Path to file contains Couchbase password (default to /etc/jans/conf/couchbase_password ). CN_COUCHBASE_CONN_TIMEOUT : Connect timeout used when a bucket is opened (default to 10000 milliseconds). CN_COUCHBASE_CONN_MAX_WAIT : Maximum time to wait before retrying connection (default to 20000 milliseconds). CN_COUCHBASE_SCAN_CONSISTENCY : Default scan consistency; one of not_bounded , request_plus , or statement_plus (default to not_bounded ). CN_COUCHBASE_BUCKET_PREFIX : Prefix for Couchbase buckets (default to jans ). CN_COUCHBASE_TRUSTSTORE_ENABLE : Enable truststore for encrypted Couchbase connection (default to true ). CN_COUCHBASE_KEEPALIVE_INTERVAL : Keep-alive interval for Couchbase connection (default to 30000 milliseconds). CN_COUCHBASE_KEEPALIVE_TIMEOUT : Keep-alive timeout for Couchbase connection (default to 2500 milliseconds). CN_SQL_DB_DIALECT : Dialect name of SQL backend (one of mysql , pgsql ; default to mysql ). CN_SQL_DB_HOST : Host of SQL backend (default to localhost ). CN_SQL_DB_PORT : Port of SQL backend (default to 3306 ). CN_SQL_DB_NAME : Database name (default to jans ) CN_SQL_DB_USER : Username to interact with SQL backend (default to jans ). CN_GOOGLE_SPANNER_INSTANCE_ID : Instance ID of Google Spanner (default to empty string). CN_GOOGLE_SPANNER_DATABASE_ID : Database ID of Google Spanner (default to empty string). GOOGLE_PROJECT_ID : Google Project ID (default to empty string). GOOGLE_PROJECT_ID : Google Project ID (default to empty string). Used when CN_CONFIG_ADAPTER or CN_SECRET_ADAPTER set to google . CN_GOOGLE_SPANNER_INSTANCE_ID : Google Spanner instance ID. CN_GOOGLE_SPANNER_DATABASE_ID : Google Spanner database ID. GLUU_ADMIN_UI_AUTH_METHOD : Authentication method for admin-ui (default to basic ). Note, changing the value require restart to jans-config-api. Hybrid mapping # Hybrid persistence supports all available persistence types. To configure hybrid persistence and its data mapping, follow steps below: Set CN_PERSISTENCE_TYPE environment variable to hybrid Set CN_HYBRID_MAPPING with the following format: { \"default\": \"\", \"user\": \"\", \"site\": \"\", \"cache\": \"\", \"token\": \"\", \"session\": \"\", } Example: { \"default\": \"sql\", \"user\": \"spanner\", \"site\": \"sql\", \"cache\": \"sql\", \"token\": \"couchbase\", \"session\": \"spanner\", }","title":"Admin UI Docker Image"},{"location":"reference/kubernetes/docker-admin-ui/#docker-admin-ui","text":"A containerized application for Gluu Admin UI frontend.","title":"docker-admin-ui"},{"location":"reference/kubernetes/docker-admin-ui/#versions","text":"See Releases for stable versions. For bleeding-edge/unstable version, use gluufederation/admin-ui:1.0.0_dev .","title":"Versions"},{"location":"reference/kubernetes/docker-admin-ui/#environment-variables","text":"The following environment variables are supported by the container: CN_CONFIG_ADAPTER : The config backend adapter, can be consul (default), kubernetes , or google . CN_CONFIG_CONSUL_HOST : hostname or IP of Consul (default to localhost ). CN_CONFIG_CONSUL_PORT : port of Consul (default to 8500 ). CN_CONFIG_CONSUL_CONSISTENCY : Consul consistency mode (choose one of default , consistent , or stale ). Default to stale mode. CN_CONFIG_CONSUL_SCHEME : supported Consul scheme ( http or https ). CN_CONFIG_CONSUL_VERIFY : whether to verify cert or not (default to false ). CN_CONFIG_CONSUL_CACERT_FILE : path to Consul CA cert file (default to /etc/certs/consul_ca.crt ). This file will be used if it exists and CN_CONFIG_CONSUL_VERIFY set to true . CN_CONFIG_CONSUL_CERT_FILE : path to Consul cert file (default to /etc/certs/consul_client.crt ). CN_CONFIG_CONSUL_KEY_FILE : path to Consul key file (default to /etc/certs/consul_client.key ). CN_CONFIG_CONSUL_TOKEN_FILE : path to file contains ACL token (default to /etc/certs/consul_token ). CN_CONFIG_KUBERNETES_NAMESPACE : Kubernetes namespace (default to default ). CN_CONFIG_KUBERNETES_CONFIGMAP : Kubernetes configmaps name (default to jans ). CN_CONFIG_KUBERNETES_USE_KUBE_CONFIG : Load credentials from $HOME/.kube/config , only useful for non-container environment (default to false ). CN_SECRET_ADAPTER : The secrets' adapter, can be vault (default), kubernetes , or google . CN_SECRET_VAULT_VERIFY : whether to verify cert or not (default to false ). CN_SECRET_VAULT_ROLE_ID_FILE : path to file contains Vault AppRole role ID (default to /etc/certs/vault_role_id ). CN_SECRET_VAULT_SECRET_ID_FILE : path to file contains Vault AppRole secret ID (default to /etc/certs/vault_secret_id ). CN_SECRET_VAULT_CERT_FILE : path to Vault cert file (default to /etc/certs/vault_client.crt ). CN_SECRET_VAULT_KEY_FILE : path to Vault key file (default to /etc/certs/vault_client.key ). CN_SECRET_VAULT_CACERT_FILE : path to Vault CA cert file (default to /etc/certs/vault_ca.crt ). This file will be used if it exists and CN_SECRET_VAULT_VERIFY set to true . CN_SECRET_VAULT_ADDR : URL of Vault (default to http://localhost:8200 ). CN_SECRET_VAULT_NAMESPACE : Namespace used to access secrets (default to empty string). CN_SECRET_VAULT_KV_PATH : Path to KV secrets engine (default to secret ). CN_SECRET_VAULT_PREFIX : Base prefix name used to build secret path (default to jans ). CN_SECRET_VAULT_APPROLE_PATH : Path to AppRole (default to approle ). CN_SECRET_KUBERNETES_NAMESPACE : Kubernetes namespace (default to default ). CN_SECRET_KUBERNETES_CONFIGMAP : Kubernetes secrets name (default to jans ). CN_SECRET_KUBERNETES_USE_KUBE_CONFIG : Load credentials from $HOME/.kube/config , only useful for non-container environment (default to false ). CN_WAIT_MAX_TIME : How long the startup \"health checks\" should run (default to 300 seconds). CN_WAIT_SLEEP_DURATION : Delay between startup \"health checks\" (default to 10 seconds). GOOGLE_PROJECT_ID : Google Project ID (default to empty string). Used when CN_CONFIG_ADAPTER or CN_SECRET_ADAPTER set to google . GOOGLE_APPLICATION_CREDENTIALS : Optional JSON file (contains Google credentials) that can be injected into container for authentication. Refer to https://cloud.google.com/docs/authentication/provide-credentials-adc#how-to for supported credentials. CN_GOOGLE_SECRET_VERSION_ID : Janssen secret version ID in Google Secret Manager. Defaults to latest , which is recommended. CN_GOOGLE_SECRET_NAME_PREFIX : Prefix for Janssen secret in Google Secret Manager. Defaults to jans . If left jans-secret secret will be created. CN_GOOGLE_SECRET_MANAGER_PASSPHRASE : Passphrase for Janssen secret in Google Secret Manager. This is recommended to be changed and defaults to secret . CN_AUTH_BASE_URL : Base URL of auth server (default to empty). CN_CONFIG_API_BASE_URL : Base URL of config-api server (default to empty). CN_TOKEN_SERVER_BASE_URL : Base URL of token server (default to empty). CN_TOKEN_SERVER_AUTHZ_ENDPOINT : Authorization endpoint at token server (default to /jans-auth/authorize.htm ). CN_TOKEN_SERVER_TOKEN_ENDPOINT : Token endpoint at token server (default to /jans-auth/restv1/token ). CN_TOKEN_SERVER_INTROSPECTION_ENDPOINT : Introspection endpoint at token server (default to /jans-auth/restv1/introspection ). CN_TOKEN_SERVER_USERINFO_ENDPOINT : User info endpoint at token server (default to /jans-auth/restv1/userinfo ). CN_TOKEN_SERVER_CLIENT_ID : Client ID registered at token server. CN_TOKEN_SERVER_CERT_FILE : Path to token server certificate (default to /etc/certs/token_server.crt ). CN_PERSISTENCE_TYPE : Persistence backend being used (one of sql , spanner , couchbase , or hybrid ; default to sql ). CN_HYBRID_MAPPING : Specify data mapping for each persistence (default to \"{}\" ). Note this environment only takes effect when CN_PERSISTENCE_TYPE is set to hybrid . See hybrid mapping section for details. CN_COUCHBASE_URL : Address of Couchbase server (default to localhost ). CN_COUCHBASE_USER : Username of Couchbase server (default to admin ). CN_COUCHBASE_CERT_FILE : Couchbase root certificate location (default to /etc/certs/couchbase.crt ). CN_COUCHBASE_PASSWORD_FILE : Path to file contains Couchbase password (default to /etc/jans/conf/couchbase_password ). CN_COUCHBASE_CONN_TIMEOUT : Connect timeout used when a bucket is opened (default to 10000 milliseconds). CN_COUCHBASE_CONN_MAX_WAIT : Maximum time to wait before retrying connection (default to 20000 milliseconds). CN_COUCHBASE_SCAN_CONSISTENCY : Default scan consistency; one of not_bounded , request_plus , or statement_plus (default to not_bounded ). CN_COUCHBASE_BUCKET_PREFIX : Prefix for Couchbase buckets (default to jans ). CN_COUCHBASE_TRUSTSTORE_ENABLE : Enable truststore for encrypted Couchbase connection (default to true ). CN_COUCHBASE_KEEPALIVE_INTERVAL : Keep-alive interval for Couchbase connection (default to 30000 milliseconds). CN_COUCHBASE_KEEPALIVE_TIMEOUT : Keep-alive timeout for Couchbase connection (default to 2500 milliseconds). CN_SQL_DB_DIALECT : Dialect name of SQL backend (one of mysql , pgsql ; default to mysql ). CN_SQL_DB_HOST : Host of SQL backend (default to localhost ). CN_SQL_DB_PORT : Port of SQL backend (default to 3306 ). CN_SQL_DB_NAME : Database name (default to jans ) CN_SQL_DB_USER : Username to interact with SQL backend (default to jans ). CN_GOOGLE_SPANNER_INSTANCE_ID : Instance ID of Google Spanner (default to empty string). CN_GOOGLE_SPANNER_DATABASE_ID : Database ID of Google Spanner (default to empty string). GOOGLE_PROJECT_ID : Google Project ID (default to empty string). GOOGLE_PROJECT_ID : Google Project ID (default to empty string). Used when CN_CONFIG_ADAPTER or CN_SECRET_ADAPTER set to google . CN_GOOGLE_SPANNER_INSTANCE_ID : Google Spanner instance ID. CN_GOOGLE_SPANNER_DATABASE_ID : Google Spanner database ID. GLUU_ADMIN_UI_AUTH_METHOD : Authentication method for admin-ui (default to basic ). Note, changing the value require restart to jans-config-api.","title":"Environment Variables"},{"location":"reference/kubernetes/docker-admin-ui/#hybrid-mapping","text":"Hybrid persistence supports all available persistence types. To configure hybrid persistence and its data mapping, follow steps below: Set CN_PERSISTENCE_TYPE environment variable to hybrid Set CN_HYBRID_MAPPING with the following format: { \"default\": \"\", \"user\": \"\", \"site\": \"\", \"cache\": \"\", \"token\": \"\", \"session\": \"\", } Example: { \"default\": \"sql\", \"user\": \"spanner\", \"site\": \"sql\", \"cache\": \"sql\", \"token\": \"couchbase\", \"session\": \"spanner\", }","title":"Hybrid mapping"},{"location":"reference/kubernetes/docker-flex-monolith/","tags":["administration","reference","kubernetes","docker image","docker compose"],"text":"Warning This image is for testing and development purposes only. Use Flex helm charts for production setups. Overview # Docker monolith image packaging for Gluu Flex. This image packs janssen services including the auth-server, config-api, fido2, casa, scim and the Gluu admin ui. Pre-requisites # Docker Docker compose Versions # See Releases for stable versions. This image should never be used in production. For bleeding-edge/unstable version, use gluufederation/monolith:5.0.0_dev . Environment Variables # Installation depends on the set of environment variables shown below. These environment variables can be set to customize installation as per the need. If not set, the installer uses default values. ENV Description Default CN_HOSTNAME Hostname to install gluu with. demoexample.gluu.org CN_ADMIN_PASS Password of the admin user. 1t5Fin3#security CN_ORG_NAME Organization name. Used for ssl cert generation. Gluu CN_EMAIL Email. Used for ssl cert generation. team@gluu.org CN_CITY City. Used for ssl cert generation. Austin CN_STATE State. Used for ssl cert generation TX CN_COUNTRY Country. Used for ssl cert generation. US CN_INSTALL_MYSQL Install gluu with mysql as the backend false CN_INSTALL_PGSQL Install gluu with Postgres as the backend false CN_INSTALL_ADMIN_UI Installs the Admin-UI true CN_INSTALL_CONFIG_API Installs the Config API service. true CN_INSTALL_SCIM Installs the SCIM API service. true CN_INSTALL_FIDO2 Installs the FIDO2 API service. true RDBMS_DATABASE RDBMS gluu database for MySQL or Postgres. gluu RDBMS_USER RDBMS database user for MySQL or Postgres. gluu RDBMS_PASSWORD RDBMS database user password for MySQL or Postgres. 1t5Fin3#security RDBMS_HOST RDBMS host for MySQL or Postgres. mysql which is the docker compose service name TEST_CLIENT_ID ID of test client in UUID which has all available scopes to access any gluu API 9876baac-de39-4c23-8a78-674b59df8c09 TEST_CLIENT_SECRET Secret for test client 1t5Fin3#security TEST_CLIENT_TRUSTED Trust test client true TEST_CLIENT_REDIRECT_URI Not Implemented yet Redirect URI for test client. Multiple uri's with comma may be provided, if not provided redirect uris will be same as the config-api-client `` How to run # Download the compose file of your chosen persistence from mysql or postgres wget https://raw.githubusercontent.com/GluuFederation/flex/main/docker-flex-monolith/flex-mysql-compose.yml wget https://raw.githubusercontent.com/GluuFederation/flex/main/docker-flex-monolith/flex-postgres-compose.yml Download the script files wget https://raw.githubusercontent.com/GluuFederation/flex/main/docker-flex-monolith/up.sh wget https://raw.githubusercontent.com/GluuFederation/flex/main/docker-flex-monolith/down.sh wget https://raw.githubusercontent.com/GluuFederation/flex/main/docker-flex-monolith/clean.sh Give execute permission to the scripts chmod u+x up.sh down.sh clean.sh This docker compose file runs two containers, the flex monolith container and mysql container. To start the containers. ./up.sh #You can pass mysql|postgres as an argument to the script. If you don't pass any, it will default to mysql. To view the containers running docker compose -f flex-mysql-compose.yml ps To stop the containers. ./down.sh #You can pass mysql|postgres as an argument to the script. If you don't pass any, it will default to mysql. Configure Gluu flex # Access the Docker container shell using: docker compose -f flex-mysql-compose.yml exec flex /bin/bash #This opens a bash terminal in the running container You can grab client_id and client_pw (secret), and other values from setup.properties or /opt/jans/jans-setup/setup.properties.last Use the CLI tools located under /opt/jans/jans-cli/ to configure Gluu flex as needed. For example you can run the TUI : python3 /opt/jans/jans-cli/config-cli-tui.py Access endpoints externally # Add to your /etc/hosts file the ip domain record which should be the ip of the instance docker is installed at and the domain used in the env above CN_HOSTNAME . # For-example 172 .22.0.3 demoexample.gluu.org After adding the record you can hit endpoints such as https://demoexample.gluu.org/.well-known/openid-configuration Clean up # Remove setup and volumes ./clean.sh #You can pass mysql|postgres as an argument to the script. If you don't pass any, it will default to mysql.","title":"Flex Monolith Docker Image"},{"location":"reference/kubernetes/docker-flex-monolith/#overview","text":"Docker monolith image packaging for Gluu Flex. This image packs janssen services including the auth-server, config-api, fido2, casa, scim and the Gluu admin ui.","title":"Overview"},{"location":"reference/kubernetes/docker-flex-monolith/#pre-requisites","text":"Docker Docker compose","title":"Pre-requisites"},{"location":"reference/kubernetes/docker-flex-monolith/#versions","text":"See Releases for stable versions. This image should never be used in production. For bleeding-edge/unstable version, use gluufederation/monolith:5.0.0_dev .","title":"Versions"},{"location":"reference/kubernetes/docker-flex-monolith/#environment-variables","text":"Installation depends on the set of environment variables shown below. These environment variables can be set to customize installation as per the need. If not set, the installer uses default values. ENV Description Default CN_HOSTNAME Hostname to install gluu with. demoexample.gluu.org CN_ADMIN_PASS Password of the admin user. 1t5Fin3#security CN_ORG_NAME Organization name. Used for ssl cert generation. Gluu CN_EMAIL Email. Used for ssl cert generation. team@gluu.org CN_CITY City. Used for ssl cert generation. Austin CN_STATE State. Used for ssl cert generation TX CN_COUNTRY Country. Used for ssl cert generation. US CN_INSTALL_MYSQL Install gluu with mysql as the backend false CN_INSTALL_PGSQL Install gluu with Postgres as the backend false CN_INSTALL_ADMIN_UI Installs the Admin-UI true CN_INSTALL_CONFIG_API Installs the Config API service. true CN_INSTALL_SCIM Installs the SCIM API service. true CN_INSTALL_FIDO2 Installs the FIDO2 API service. true RDBMS_DATABASE RDBMS gluu database for MySQL or Postgres. gluu RDBMS_USER RDBMS database user for MySQL or Postgres. gluu RDBMS_PASSWORD RDBMS database user password for MySQL or Postgres. 1t5Fin3#security RDBMS_HOST RDBMS host for MySQL or Postgres. mysql which is the docker compose service name TEST_CLIENT_ID ID of test client in UUID which has all available scopes to access any gluu API 9876baac-de39-4c23-8a78-674b59df8c09 TEST_CLIENT_SECRET Secret for test client 1t5Fin3#security TEST_CLIENT_TRUSTED Trust test client true TEST_CLIENT_REDIRECT_URI Not Implemented yet Redirect URI for test client. Multiple uri's with comma may be provided, if not provided redirect uris will be same as the config-api-client ``","title":"Environment Variables"},{"location":"reference/kubernetes/docker-flex-monolith/#how-to-run","text":"Download the compose file of your chosen persistence from mysql or postgres wget https://raw.githubusercontent.com/GluuFederation/flex/main/docker-flex-monolith/flex-mysql-compose.yml wget https://raw.githubusercontent.com/GluuFederation/flex/main/docker-flex-monolith/flex-postgres-compose.yml Download the script files wget https://raw.githubusercontent.com/GluuFederation/flex/main/docker-flex-monolith/up.sh wget https://raw.githubusercontent.com/GluuFederation/flex/main/docker-flex-monolith/down.sh wget https://raw.githubusercontent.com/GluuFederation/flex/main/docker-flex-monolith/clean.sh Give execute permission to the scripts chmod u+x up.sh down.sh clean.sh This docker compose file runs two containers, the flex monolith container and mysql container. To start the containers. ./up.sh #You can pass mysql|postgres as an argument to the script. If you don't pass any, it will default to mysql. To view the containers running docker compose -f flex-mysql-compose.yml ps To stop the containers. ./down.sh #You can pass mysql|postgres as an argument to the script. If you don't pass any, it will default to mysql.","title":"How to run"},{"location":"reference/kubernetes/docker-flex-monolith/#configure-gluu-flex","text":"Access the Docker container shell using: docker compose -f flex-mysql-compose.yml exec flex /bin/bash #This opens a bash terminal in the running container You can grab client_id and client_pw (secret), and other values from setup.properties or /opt/jans/jans-setup/setup.properties.last Use the CLI tools located under /opt/jans/jans-cli/ to configure Gluu flex as needed. For example you can run the TUI : python3 /opt/jans/jans-cli/config-cli-tui.py","title":"Configure Gluu flex"},{"location":"reference/kubernetes/docker-flex-monolith/#access-endpoints-externally","text":"Add to your /etc/hosts file the ip domain record which should be the ip of the instance docker is installed at and the domain used in the env above CN_HOSTNAME . # For-example 172 .22.0.3 demoexample.gluu.org After adding the record you can hit endpoints such as https://demoexample.gluu.org/.well-known/openid-configuration","title":"Access endpoints externally"},{"location":"reference/kubernetes/docker-flex-monolith/#clean-up","text":"Remove setup and volumes ./clean.sh #You can pass mysql|postgres as an argument to the script. If you don't pass any, it will default to mysql.","title":"Clean up"},{"location":"reference/kubernetes/helm-chart/","text":"gluu # Gluu Access and Identity Management Homepage: https://www.gluu.org Maintainers # Name Email Url moabu team@gluu.org Source Code # https://docs.gluu.org Requirements # Kubernetes: >=v1.21.0-0 Repository Name Version admin-ui 5.1.4 auth-server 1.1.4 auth-server-key-rotation 1.1.4 casa 1.1.4 cn-istio-ingress 5.1.4 config 1.1.4 config-api 1.1.4 fido2 1.1.4 kc-scheduler 1.1.4 link 1.1.4 nginx-ingress 5.1.4 persistence 1.1.4 saml 1.1.4 scim 1.1.4 Values # Key Type Default Description admin-ui object {\"additionalAnnotations\":{},\"additionalLabels\":{},\"customScripts\":[],\"dnsConfig\":{},\"dnsPolicy\":\"\",\"hpa\":{\"behavior\":{},\"enabled\":true,\"maxReplicas\":10,\"metrics\":[],\"minReplicas\":1,\"targetCPUUtilizationPercentage\":50},\"image\":{\"pullPolicy\":\"IfNotPresent\",\"pullSecrets\":[],\"repository\":\"ghcr.io/gluufederation/flex/admin-ui\",\"tag\":\"5.1.3-1\"},\"lifecycle\":{},\"livenessProbe\":{\"failureThreshold\":20,\"initialDelaySeconds\":60,\"periodSeconds\":25,\"tcpSocket\":{\"port\":8080},\"timeoutSeconds\":5},\"pdb\":{\"enabled\":true,\"maxUnavailable\":\"90%\"},\"readinessProbe\":{\"failureThreshold\":20,\"initialDelaySeconds\":60,\"periodSeconds\":25,\"tcpSocket\":{\"port\":8080},\"timeoutSeconds\":5},\"replicas\":1,\"resources\":{\"limits\":{\"cpu\":\"2000m\",\"memory\":\"2000Mi\"},\"requests\":{\"cpu\":\"2000m\",\"memory\":\"2000Mi\"}},\"topologySpreadConstraints\":{},\"usrEnvs\":{\"normal\":{},\"secret\":{}},\"volumeMounts\":[],\"volumes\":[]} Admin GUI for configuration of the auth-server admin-ui.additionalAnnotations object {} Additional annotations that will be added across the gateway in the format of admin-ui.additionalLabels object {} Additional labels that will be added across the gateway in the format of admin-ui.customScripts list [] Add custom scripts that have been mounted to run before the entrypoint. - /tmp/custom.sh - /tmp/custom2.sh admin-ui.dnsConfig object {} Add custom dns config admin-ui.dnsPolicy string \"\" Add custom dns policy admin-ui.hpa object {\"behavior\":{},\"enabled\":true,\"maxReplicas\":10,\"metrics\":[],\"minReplicas\":1,\"targetCPUUtilizationPercentage\":50} Configure the HorizontalPodAutoscaler admin-ui.hpa.behavior object {} Scaling Policies admin-ui.hpa.metrics list [] metrics if targetCPUUtilizationPercentage is not set admin-ui.image.pullPolicy string \"IfNotPresent\" Image pullPolicy to use for deploying. admin-ui.image.pullSecrets list [] Image Pull Secrets admin-ui.image.repository string \"ghcr.io/gluufederation/flex/admin-ui\" Image to use for deploying. admin-ui.image.tag string \"5.1.3-1\" Image tag to use for deploying. admin-ui.livenessProbe object {\"failureThreshold\":20,\"initialDelaySeconds\":60,\"periodSeconds\":25,\"tcpSocket\":{\"port\":8080},\"timeoutSeconds\":5} Configure the liveness healthcheck for the admin ui if needed. admin-ui.pdb object {\"enabled\":true,\"maxUnavailable\":\"90%\"} Configure the PodDisruptionBudget admin-ui.readinessProbe object {\"failureThreshold\":20,\"initialDelaySeconds\":60,\"periodSeconds\":25,\"tcpSocket\":{\"port\":8080},\"timeoutSeconds\":5} Configure the readiness healthcheck for the admin ui if needed. admin-ui.replicas int 1 Service replica number. admin-ui.resources object {\"limits\":{\"cpu\":\"2000m\",\"memory\":\"2000Mi\"},\"requests\":{\"cpu\":\"2000m\",\"memory\":\"2000Mi\"}} Resource specs. admin-ui.resources.limits.cpu string \"2000m\" CPU limit. admin-ui.resources.limits.memory string \"2000Mi\" Memory limit. admin-ui.resources.requests.cpu string \"2000m\" CPU request. admin-ui.resources.requests.memory string \"2000Mi\" Memory request. admin-ui.topologySpreadConstraints object {} Configure the topology spread constraints. Notice this is a map NOT a list as in the upstream API https://kubernetes.io/docs/concepts/scheduling-eviction/topology-spread-constraints/ admin-ui.usrEnvs object {\"normal\":{},\"secret\":{}} Add custom normal and secret envs to the service admin-ui.usrEnvs.normal object {} Add custom normal envs to the service variable1: value1 admin-ui.usrEnvs.secret object {} Add custom secret envs to the service variable1: value1 admin-ui.volumeMounts list [] Configure any additional volumesMounts that need to be attached to the containers admin-ui.volumes list [] Configure any additional volumes that need to be attached to the pod auth-server object {\"additionalAnnotations\":{},\"additionalLabels\":{},\"customScripts\":[],\"dnsConfig\":{},\"dnsPolicy\":\"\",\"hpa\":{\"behavior\":{},\"enabled\":true,\"maxReplicas\":10,\"metrics\":[],\"minReplicas\":1,\"targetCPUUtilizationPercentage\":50},\"image\":{\"pullPolicy\":\"IfNotPresent\",\"pullSecrets\":[],\"repository\":\"ghcr.io/janssenproject/jans/auth-server\",\"tag\":\"1.1.6_dev\"},\"lifecycle\":{},\"livenessProbe\":{\"exec\":{\"command\":[\"python3\",\"/app/scripts/healthcheck.py\"]},\"initialDelaySeconds\":30,\"periodSeconds\":30,\"timeoutSeconds\":5},\"pdb\":{\"enabled\":true,\"maxUnavailable\":\"90%\"},\"readinessProbe\":{\"exec\":{\"command\":[\"python3\",\"/app/scripts/healthcheck.py\"]},\"initialDelaySeconds\":25,\"periodSeconds\":25,\"timeoutSeconds\":5},\"replicas\":1,\"resources\":{\"limits\":{\"cpu\":\"2500m\",\"memory\":\"2500Mi\"},\"requests\":{\"cpu\":\"2500m\",\"memory\":\"2500Mi\"}},\"topologySpreadConstraints\":{},\"usrEnvs\":{\"normal\":{},\"secret\":{}},\"volumeMounts\":[],\"volumes\":[]} OAuth Authorization Server, the OpenID Connect Provider, the UMA Authorization Server--this is the main Internet facing component of Gluu. It's the service that returns tokens, JWT's and identity assertions. This service must be Internet facing. auth-server-key-rotation object {\"additionalAnnotations\":{},\"additionalLabels\":{},\"customScripts\":[],\"dnsConfig\":{},\"dnsPolicy\":\"\",\"image\":{\"pullPolicy\":\"IfNotPresent\",\"pullSecrets\":[],\"repository\":\"ghcr.io/janssenproject/jans/certmanager\",\"tag\":\"1.1.6_dev\"},\"keysLife\":48,\"keysPushDelay\":0,\"keysPushStrategy\":\"NEWER\",\"keysStrategy\":\"NEWER\",\"lifecycle\":{},\"resources\":{\"limits\":{\"cpu\":\"300m\",\"memory\":\"300Mi\"},\"requests\":{\"cpu\":\"300m\",\"memory\":\"300Mi\"}},\"usrEnvs\":{\"normal\":{},\"secret\":{}},\"volumeMounts\":[],\"volumes\":[]} Responsible for regenerating auth-keys per x hours auth-server-key-rotation.additionalAnnotations object {} Additional annotations that will be added across the gateway in the format of auth-server-key-rotation.additionalLabels object {} Additional labels that will be added across the gateway in the format of auth-server-key-rotation.customScripts list [] Add custom scripts that have been mounted to run before the entrypoint. - /tmp/custom.sh - /tmp/custom2.sh auth-server-key-rotation.dnsConfig object {} Add custom dns config auth-server-key-rotation.dnsPolicy string \"\" Add custom dns policy auth-server-key-rotation.image.pullPolicy string \"IfNotPresent\" Image pullPolicy to use for deploying. auth-server-key-rotation.image.pullSecrets list [] Image Pull Secrets auth-server-key-rotation.image.repository string \"ghcr.io/janssenproject/jans/certmanager\" Image to use for deploying. auth-server-key-rotation.image.tag string \"1.1.3-1\" Image tag to use for deploying. auth-server-key-rotation.keysLife int 48 Auth server key rotation keys life in hours auth-server-key-rotation.keysPushDelay int 0 Delay (in seconds) before pushing private keys to Auth server auth-server-key-rotation.keysPushStrategy string \"NEWER\" Set key selection strategy after pushing private keys to Auth server (only takes effect when keysPushDelay value is greater than 0) auth-server-key-rotation.keysStrategy string \"NEWER\" Set key selection strategy used by Auth server auth-server-key-rotation.resources object {\"limits\":{\"cpu\":\"300m\",\"memory\":\"300Mi\"},\"requests\":{\"cpu\":\"300m\",\"memory\":\"300Mi\"}} Resource specs. auth-server-key-rotation.resources.limits.cpu string \"300m\" CPU limit. auth-server-key-rotation.resources.limits.memory string \"300Mi\" Memory limit. auth-server-key-rotation.resources.requests.cpu string \"300m\" CPU request. auth-server-key-rotation.resources.requests.memory string \"300Mi\" Memory request. auth-server-key-rotation.usrEnvs object {\"normal\":{},\"secret\":{}} Add custom normal and secret envs to the service auth-server-key-rotation.usrEnvs.normal object {} Add custom normal envs to the service variable1: value1 auth-server-key-rotation.usrEnvs.secret object {} Add custom secret envs to the service variable1: value1 auth-server-key-rotation.volumeMounts list [] Configure any additional volumesMounts that need to be attached to the containers auth-server-key-rotation.volumes list [] Configure any additional volumes that need to be attached to the pod auth-server.additionalAnnotations object {} Additional annotations that will be added across the gateway in the format of auth-server.additionalLabels object {} Additional labels that will be added across the gateway in the format of auth-server.customScripts list [] Add custom scripts that have been mounted to run before the entrypoint. - /tmp/custom.sh - /tmp/custom2.sh auth-server.dnsConfig object {} Add custom dns config auth-server.dnsPolicy string \"\" Add custom dns policy auth-server.hpa object {\"behavior\":{},\"enabled\":true,\"maxReplicas\":10,\"metrics\":[],\"minReplicas\":1,\"targetCPUUtilizationPercentage\":50} Configure the HorizontalPodAutoscaler auth-server.hpa.behavior object {} Scaling Policies auth-server.hpa.metrics list [] metrics if targetCPUUtilizationPercentage is not set auth-server.image.pullPolicy string \"IfNotPresent\" Image pullPolicy to use for deploying. auth-server.image.pullSecrets list [] Image Pull Secrets auth-server.image.repository string \"ghcr.io/janssenproject/jans/auth-server\" Image to use for deploying. auth-server.image.tag string \"1.1.6_dev\" Image tag to use for deploying. auth-server.livenessProbe object {\"exec\":{\"command\":[\"python3\",\"/app/scripts/healthcheck.py\"]},\"initialDelaySeconds\":30,\"periodSeconds\":30,\"timeoutSeconds\":5} Configure the liveness healthcheck for the auth server if needed. auth-server.livenessProbe.exec object {\"command\":[\"python3\",\"/app/scripts/healthcheck.py\"]} Executes the python3 healthcheck. https://github.com/JanssenProject/docker-jans-auth-server/blob/master/scripts/healthcheck.py auth-server.pdb object {\"enabled\":true,\"maxUnavailable\":\"90%\"} Configure the PodDisruptionBudget auth-server.readinessProbe object {\"exec\":{\"command\":[\"python3\",\"/app/scripts/healthcheck.py\"]},\"initialDelaySeconds\":25,\"periodSeconds\":25,\"timeoutSeconds\":5} Configure the readiness healthcheck for the auth server if needed. https://github.com/JanssenProject/docker-jans-auth-server/blob/master/scripts/healthcheck.py auth-server.replicas int 1 Service replica number. auth-server.resources object {\"limits\":{\"cpu\":\"2500m\",\"memory\":\"2500Mi\"},\"requests\":{\"cpu\":\"2500m\",\"memory\":\"2500Mi\"}} Resource specs. auth-server.resources.limits.cpu string \"2500m\" CPU limit. auth-server.resources.limits.memory string \"2500Mi\" Memory limit. This value is used to calculate memory allocation for Java. Currently it only supports Mi . Please refrain from using other units. auth-server.resources.requests.cpu string \"2500m\" CPU request. auth-server.resources.requests.memory string \"2500Mi\" Memory request. auth-server.topologySpreadConstraints object {} Configure the topology spread constraints. Notice this is a map NOT a list as in the upstream API https://kubernetes.io/docs/concepts/scheduling-eviction/topology-spread-constraints/ auth-server.usrEnvs object {\"normal\":{},\"secret\":{}} Add custom normal and secret envs to the service auth-server.usrEnvs.normal object {} Add custom normal envs to the service variable1: value1 auth-server.usrEnvs.secret object {} Add custom secret envs to the service variable1: value1 auth-server.volumeMounts list [] Configure any additional volumesMounts that need to be attached to the containers auth-server.volumes list [] Configure any additional volumes that need to be attached to the pod casa object {\"additionalAnnotations\":{},\"additionalLabels\":{},\"customScripts\":[],\"dnsConfig\":{},\"dnsPolicy\":\"\",\"hpa\":{\"behavior\":{},\"enabled\":true,\"maxReplicas\":10,\"metrics\":[],\"minReplicas\":1,\"targetCPUUtilizationPercentage\":50},\"image\":{\"pullPolicy\":\"IfNotPresent\",\"pullSecrets\":[],\"repository\":\"ghcr.io/janssenproject/jans/casa\",\"tag\":\"1.1.6_dev\"},\"lifecycle\":{},\"livenessProbe\":{\"httpGet\":{\"path\":\"/jans-casa/health-check\",\"port\":\"http-casa\"},\"initialDelaySeconds\":25,\"periodSeconds\":25,\"timeoutSeconds\":5},\"pdb\":{\"enabled\":true,\"maxUnavailable\":\"90%\"},\"readinessProbe\":{\"httpGet\":{\"path\":\"/jans-casa/health-check\",\"port\":\"http-casa\"},\"initialDelaySeconds\":30,\"periodSeconds\":30,\"timeoutSeconds\":5},\"replicas\":1,\"resources\":{\"limits\":{\"cpu\":\"500m\",\"memory\":\"500Mi\"},\"requests\":{\"cpu\":\"500m\",\"memory\":\"500Mi\"}},\"topologySpreadConstraints\":{},\"usrEnvs\":{\"normal\":{},\"secret\":{}},\"volumeMounts\":[],\"volumes\":[]} Janssen Casa (\"Casa\") is a self-service web portal for end-users to manage authentication and authorization preferences for their account in a Janssen Auth Server. casa.additionalAnnotations object {} Additional annotations that will be added across the gateway in the format of casa.additionalLabels object {} Additional labels that will be added across the gateway in the format of casa.customScripts list [] Add custom scripts that have been mounted to run before the entrypoint. - /tmp/custom.sh - /tmp/custom2.sh casa.dnsConfig object {} Add custom dns config casa.dnsPolicy string \"\" Add custom dns policy casa.hpa object {\"behavior\":{},\"enabled\":true,\"maxReplicas\":10,\"metrics\":[],\"minReplicas\":1,\"targetCPUUtilizationPercentage\":50} Configure the HorizontalPodAutoscaler casa.hpa.behavior object {} Scaling Policies casa.hpa.metrics list [] metrics if targetCPUUtilizationPercentage is not set casa.image.pullPolicy string \"IfNotPresent\" Image pullPolicy to use for deploying. casa.image.pullSecrets list [] Image Pull Secrets casa.image.repository string \"ghcr.io/janssenproject/jans/casa\" Image to use for deploying. casa.image.tag string \"1.1.6_dev\" Image tag to use for deploying. casa.livenessProbe object {\"httpGet\":{\"path\":\"/jans-casa/health-check\",\"port\":\"http-casa\"},\"initialDelaySeconds\":25,\"periodSeconds\":25,\"timeoutSeconds\":5} Configure the liveness healthcheck for casa if needed. casa.livenessProbe.httpGet.path string \"/jans-casa/health-check\" http liveness probe endpoint casa.pdb object {\"enabled\":true,\"maxUnavailable\":\"90%\"} Configure the PodDisruptionBudget casa.readinessProbe object {\"httpGet\":{\"path\":\"/jans-casa/health-check\",\"port\":\"http-casa\"},\"initialDelaySeconds\":30,\"periodSeconds\":30,\"timeoutSeconds\":5} Configure the readiness healthcheck for the casa if needed. casa.readinessProbe.httpGet.path string \"/jans-casa/health-check\" http readiness probe endpoint casa.replicas int 1 Service replica number. casa.resources object {\"limits\":{\"cpu\":\"500m\",\"memory\":\"500Mi\"},\"requests\":{\"cpu\":\"500m\",\"memory\":\"500Mi\"}} Resource specs. casa.resources.limits.cpu string \"500m\" CPU limit. casa.resources.limits.memory string \"500Mi\" Memory limit. This value is used to calculate memory allocation for Java. Currently it only supports Mi . Please refrain from using other units. casa.resources.requests.cpu string \"500m\" CPU request. casa.resources.requests.memory string \"500Mi\" Memory request. casa.topologySpreadConstraints object {} Configure the topology spread constraints. Notice this is a map NOT a list as in the upstream API https://kubernetes.io/docs/concepts/scheduling-eviction/topology-spread-constraints/ casa.usrEnvs object {\"normal\":{},\"secret\":{}} Add custom normal and secret envs to the service casa.usrEnvs.normal object {} Add custom normal envs to the service variable1: value1 casa.usrEnvs.secret object {} Add custom secret envs to the service variable1: value1 casa.volumeMounts list [] Configure any additional volumesMounts that need to be attached to the containers casa.volumes list [] Configure any additional volumes that need to be attached to the pod config object {\"additionalAnnotations\":{},\"additionalLabels\":{},\"adminPassword\":\"Test1234#\",\"city\":\"Austin\",\"configmap\":{\"cnAwsAccessKeyId\":\"\",\"cnAwsDefaultRegion\":\"us-west-1\",\"cnAwsProfile\":\"gluu\",\"cnAwsSecretAccessKey\":\"\",\"cnAwsSecretsEndpointUrl\":\"\",\"cnAwsSecretsNamePrefix\":\"gluu\",\"cnAwsSecretsReplicaRegions\":[],\"cnCacheType\":\"NATIVE_PERSISTENCE\",\"cnConfigKubernetesConfigMap\":\"cn\",\"cnCouchbaseBucketPrefix\":\"jans\",\"cnCouchbaseCrt\":\"SWFtTm90YVNlcnZpY2VBY2NvdW50Q2hhbmdlTWV0b09uZQo=\",\"cnCouchbaseIndexNumReplica\":0,\"cnCouchbasePassword\":\"P@ssw0rd\",\"cnCouchbaseSuperUser\":\"admin\",\"cnCouchbaseSuperUserPassword\":\"Test1234#\",\"cnCouchbaseUrl\":\"cbgluu.default.svc.cluster.local\",\"cnCouchbaseUser\":\"gluu\",\"cnGoogleProjectId\":\"google-project-to-save-config-and-secrets-to\",\"cnGoogleSecretManagerServiceAccount\":\"SWFtTm90YVNlcnZpY2VBY2NvdW50Q2hhbmdlTWV0b09uZQo=\",\"cnGoogleSecretNamePrefix\":\"gluu\",\"cnGoogleSecretVersionId\":\"latest\",\"cnGoogleSpannerDatabaseId\":\"\",\"cnGoogleSpannerInstanceId\":\"\",\"cnJettyRequestHeaderSize\":8192,\"cnLdapCrt\":\"SWFtTm90YVNlcnZpY2VBY2NvdW50Q2hhbmdlTWV0b09uZQo=\",\"cnLdapKey\":\"SWFtTm90YVNlcnZpY2VBY2NvdW50Q2hhbmdlTWV0b09uZQo=\",\"cnLdapUrl\":\"opendj:1636\",\"cnMaxRamPercent\":\"75.0\",\"cnMessageType\":\"DISABLED\",\"cnOpaUrl\":\"http://opa.opa.svc.cluster.cluster.local:8181/v1\",\"cnPersistenceHybridMapping\":\"{}\",\"cnRedisSentinelGroup\":\"\",\"cnRedisSslTruststore\":\"\",\"cnRedisType\":\"STANDALONE\",\"cnRedisUrl\":\"redis.redis.svc.cluster.local:6379\",\"cnRedisUseSsl\":false,\"cnScimProtectionMode\":\"OAUTH\",\"cnSecretKubernetesSecret\":\"cn\",\"cnSqlDbDialect\":\"mysql\",\"cnSqlDbHost\":\"my-release-mysql.default.svc.cluster.local\",\"cnSqlDbName\":\"gluu\",\"cnSqlDbPort\":3306,\"cnSqlDbSchema\":\"\",\"cnSqlDbTimezone\":\"UTC\",\"cnSqlDbUser\":\"gluu\",\"cnSqldbUserPassword\":\"Test1234#\",\"cnVaultAddr\":\"http://localhost:8200\",\"cnVaultAppRolePath\":\"approle\",\"cnVaultKvPath\":\"secret\",\"cnVaultNamespace\":\"\",\"cnVaultPrefix\":\"jans\",\"cnVaultRoleId\":\"\",\"cnVaultRoleIdFile\":\"/etc/certs/vault_role_id\",\"cnVaultSecretId\":\"\",\"cnVaultSecretIdFile\":\"/etc/certs/vault_secret_id\",\"cnVaultVerify\":false,\"kcDbPassword\":\"Test1234#\",\"kcDbSchema\":\"keycloak\",\"kcDbUrlDatabase\":\"keycloak\",\"kcDbUrlHost\":\"mysql.kc.svc.cluster.local\",\"kcDbUrlPort\":3306,\"kcDbUrlProperties\":\"?useUnicode=true&characterEncoding=UTF-8&character_set_server=utf8mb4\",\"kcDbUsername\":\"keycloak\",\"kcDbVendor\":\"mysql\",\"kcLogLevel\":\"INFO\",\"lbAddr\":\"\",\"quarkusTransactionEnableRecovery\":true},\"countryCode\":\"US\",\"customScripts\":[],\"dnsConfig\":{},\"dnsPolicy\":\"\",\"email\":\"team@gluu.org\",\"image\":{\"pullSecrets\":[],\"repository\":\"ghcr.io/janssenproject/jans/configurator\",\"tag\":\"1.1.6_dev\"},\"ldapPassword\":\"P@ssw0rds\",\"ldapTruststorePassword\":\"changeit\",\"lifecycle\":{},\"migration\":{\"enabled\":false,\"migrationDataFormat\":\"ldif\",\"migrationDir\":\"/ce-migration\"},\"orgName\":\"Gluu\",\"redisPassword\":\"P@assw0rd\",\"resources\":{\"limits\":{\"cpu\":\"300m\",\"memory\":\"300Mi\"},\"requests\":{\"cpu\":\"300m\",\"memory\":\"300Mi\"}},\"salt\":\"\",\"state\":\"TX\",\"usrEnvs\":{\"normal\":{},\"secret\":{}},\"volumeMounts\":[],\"volumes\":[]} Configuration parameters for setup and initial configuration secret and config layers used by Gluu services. config-api object {\"additionalAnnotations\":{},\"additionalLabels\":{},\"customScripts\":[],\"dnsConfig\":{},\"dnsPolicy\":\"\",\"hpa\":{\"behavior\":{},\"enabled\":true,\"maxReplicas\":10,\"metrics\":[],\"minReplicas\":1,\"targetCPUUtilizationPercentage\":50},\"image\":{\"pullPolicy\":\"IfNotPresent\",\"pullSecrets\":[],\"repository\":\"ghcr.io/janssenproject/jans/config-api\",\"tag\":\"1.1.6_dev\"},\"lifecycle\":{},\"livenessProbe\":{\"httpGet\":{\"path\":\"/jans-config-api/api/v1/health/live\",\"port\":8074},\"initialDelaySeconds\":30,\"periodSeconds\":30,\"timeoutSeconds\":5},\"pdb\":{\"enabled\":true,\"maxUnavailable\":\"90%\"},\"readinessProbe\":{\"httpGet\":{\"path\":\"jans-config-api/api/v1/health/ready\",\"port\":8074},\"initialDelaySeconds\":25,\"periodSeconds\":25,\"timeoutSeconds\":5},\"replicas\":1,\"resources\":{\"limits\":{\"cpu\":\"1000m\",\"memory\":\"1200Mi\"},\"requests\":{\"cpu\":\"1000m\",\"memory\":\"1200Mi\"}},\"topologySpreadConstraints\":{},\"usrEnvs\":{\"normal\":{},\"secret\":{}},\"volumeMounts\":[],\"volumes\":[]} Config Api endpoints can be used to configure the auth-server, which is an open-source OpenID Connect Provider (OP) and UMA Authorization Server (AS). config-api.additionalAnnotations object {} Additional annotations that will be added across the gateway in the format of config-api.additionalLabels object {} Additional labels that will be added across the gateway in the format of config-api.customScripts list [] Add custom scripts that have been mounted to run before the entrypoint. - /tmp/custom.sh - /tmp/custom2.sh config-api.dnsConfig object {} Add custom dns config config-api.dnsPolicy string \"\" Add custom dns policy config-api.hpa object {\"behavior\":{},\"enabled\":true,\"maxReplicas\":10,\"metrics\":[],\"minReplicas\":1,\"targetCPUUtilizationPercentage\":50} Configure the HorizontalPodAutoscaler config-api.hpa.behavior object {} Scaling Policies config-api.hpa.metrics list [] metrics if targetCPUUtilizationPercentage is not set config-api.image.pullPolicy string \"IfNotPresent\" Image pullPolicy to use for deploying. config-api.image.pullSecrets list [] Image Pull Secrets config-api.image.repository string \"ghcr.io/janssenproject/jans/config-api\" Image to use for deploying. config-api.image.tag string \"1.1.6_dev\" Image tag to use for deploying. config-api.livenessProbe object {\"httpGet\":{\"path\":\"/jans-config-api/api/v1/health/live\",\"port\":8074},\"initialDelaySeconds\":30,\"periodSeconds\":30,\"timeoutSeconds\":5} Configure the liveness healthcheck for the auth server if needed. config-api.livenessProbe.httpGet object {\"path\":\"/jans-config-api/api/v1/health/live\",\"port\":8074} http liveness probe endpoint config-api.pdb object {\"enabled\":true,\"maxUnavailable\":\"90%\"} Configure the PodDisruptionBudget config-api.readinessProbe.httpGet object {\"path\":\"jans-config-api/api/v1/health/ready\",\"port\":8074} http readiness probe endpoint config-api.replicas int 1 Service replica number. config-api.resources object {\"limits\":{\"cpu\":\"1000m\",\"memory\":\"1200Mi\"},\"requests\":{\"cpu\":\"1000m\",\"memory\":\"1200Mi\"}} Resource specs. config-api.resources.limits.cpu string \"1000m\" CPU limit. config-api.resources.limits.memory string \"1200Mi\" Memory limit. This value is used to calculate memory allocation for Java. Currently it only supports Mi . Please refrain from using other units. config-api.resources.requests.cpu string \"1000m\" CPU request. config-api.resources.requests.memory string \"1200Mi\" Memory request. config-api.topologySpreadConstraints object {} Configure the topology spread constraints. Notice this is a map NOT a list as in the upstream API https://kubernetes.io/docs/concepts/scheduling-eviction/topology-spread-constraints/ config-api.usrEnvs object {\"normal\":{},\"secret\":{}} Add custom normal and secret envs to the service config-api.usrEnvs.normal object {} Add custom normal envs to the service variable1: value1 config-api.usrEnvs.secret object {} Add custom secret envs to the service variable1: value1 config-api.volumeMounts list [] Configure any additional volumesMounts that need to be attached to the containers config-api.volumes list [] Configure any additional volumes that need to be attached to the pod config.additionalAnnotations object {} Additional annotations that will be added across the gateway in the format of config.additionalLabels object {} Additional labels that will be added across the gateway in the format of config.adminPassword string \"Test1234#\" Admin password to log in to the UI. config.city string \"Austin\" City. Used for certificate creation. config.configmap.cnCacheType string \"NATIVE_PERSISTENCE\" Cache type. NATIVE_PERSISTENCE , REDIS . or IN_MEMORY . Defaults to NATIVE_PERSISTENCE . config.configmap.cnConfigKubernetesConfigMap string \"cn\" The name of the Kubernetes ConfigMap that will hold the configuration layer config.configmap.cnCouchbaseBucketPrefix string \"jans\" The prefix of couchbase buckets. This helps with separation in between different environments and allows for the same couchbase cluster to be used by different setups of Gluu. config.configmap.cnCouchbaseCrt string \"SWFtTm90YVNlcnZpY2VBY2NvdW50Q2hhbmdlTWV0b09uZQo=\" Couchbase certificate authority string. This must be encoded using base64. This can also be found in your couchbase UI Security > Root Certificate. In mTLS setups this is not required. config.configmap.cnCouchbaseIndexNumReplica int 0 The number of replicas per index created. Please note that the number of index nodes must be one greater than the number of index replicas. That means if your couchbase cluster only has 2 index nodes you cannot place the number of replicas to be higher than 1. config.configmap.cnCouchbasePassword string \"P@ssw0rd\" Couchbase password for the restricted user config.configmap.cnCouchbaseUser that is often used inside the services. The password must contain one digit, one uppercase letter, one lower case letter and one symbol . config.configmap.cnCouchbaseSuperUser string \"admin\" The Couchbase super user (admin) username. This user is used during initialization only. config.configmap.cnCouchbaseSuperUserPassword string \"Test1234#\" Couchbase password for the superuser config.configmap.cnCouchbaseSuperUser that is used during the initialization process. The password must contain one digit, one uppercase letter, one lower case letter and one symbol config.configmap.cnCouchbaseUrl string \"cbgluu.default.svc.cluster.local\" Couchbase URL. Used only when global.cnPersistenceType is hybrid or couchbase. This should be in FQDN format for either remote or local Couchbase clusters. The address can be an internal address inside the kubernetes cluster config.configmap.cnCouchbaseUser string \"gluu\" Couchbase restricted user. Used only when global.cnPersistenceType is hybrid or couchbase. config.configmap.cnGoogleProjectId string \"google-project-to-save-config-and-secrets-to\" Project id of the Google project the secret manager belongs to. Used only when global.configAdapterName and global.configSecretAdapter is set to google. config.configmap.cnGoogleSecretManagerServiceAccount string \"SWFtTm90YVNlcnZpY2VBY2NvdW50Q2hhbmdlTWV0b09uZQo=\" Service account with roles roles/secretmanager.admin base64 encoded string. This is used often inside the services to reach the configuration layer. Used only when global.configAdapterName and global.configSecretAdapter is set to google. config.configmap.cnGoogleSecretNamePrefix string \"gluu\" Prefix for Gluu secret in Google Secret Manager. Defaults to gluu. If left gluu-secret secret will be created. Used only when global.configAdapterName and global.configSecretAdapter is set to google. config.configmap.cnGoogleSecretVersionId string \"latest\" Secret version to be used for secret configuration. Defaults to latest and should normally always stay that way. Used only when global.configAdapterName and global.configSecretAdapter is set to google. config.configmap.cnGoogleSpannerDatabaseId string \"\" Google Spanner Database ID. Used only when global.cnPersistenceType is spanner. config.configmap.cnGoogleSpannerInstanceId string \"\" Google Spanner ID. Used only when global.cnPersistenceType is spanner. config.configmap.cnJettyRequestHeaderSize int 8192 Jetty header size in bytes in the auth server config.configmap.cnLdapCrt string \"SWFtTm90YVNlcnZpY2VBY2NvdW50Q2hhbmdlTWV0b09uZQo=\" OpenDJ certificate string. This must be encoded using base64. config.configmap.cnLdapKey string \"SWFtTm90YVNlcnZpY2VBY2NvdW50Q2hhbmdlTWV0b09uZQo=\" OpenDJ key string. This must be encoded using base64. config.configmap.cnLdapUrl string \"opendj:1636\" OpenDJ internal address. Leave as default. Used when global.cnPersistenceType is set to ldap . config.configmap.cnMaxRamPercent string \"75.0\" Value passed to Java option -XX:MaxRAMPercentage config.configmap.cnMessageType string \"DISABLED\" Message type (one of POSTGRES, REDIS, or DISABLED) config.configmap.cnOpaUrl string \"http://opa.opa.svc.cluster.cluster.local:8181/v1\" URL of OPA API config.configmap.cnPersistenceHybridMapping string \"{}\" Specify data that should be saved in LDAP (one of default, user, cache, site, token, or session; default to default). Note this environment only takes effect when global.cnPersistenceType is set to hybrid . { \"default\": \" 2022-12-20 17:49:55,744 INFO global.auth-server.appLoggers.httpLogLevel string \"INFO\" http_request_response.log level global.auth-server.appLoggers.httpLogTarget string \"FILE\" http_request_response.log target global.auth-server.appLoggers.ldapStatsLogLevel string \"INFO\" jans-auth_persistence_ldap_statistics.log level global.auth-server.appLoggers.ldapStatsLogTarget string \"FILE\" jans-auth_persistence_ldap_statistics.log target global.auth-server.appLoggers.persistenceDurationLogLevel string \"INFO\" jans-auth_persistence_duration.log level global.auth-server.appLoggers.persistenceDurationLogTarget string \"FILE\" jans-auth_persistence_duration.log target global.auth-server.appLoggers.persistenceLogLevel string \"INFO\" jans-auth_persistence.log level global.auth-server.appLoggers.persistenceLogTarget string \"FILE\" jans-auth_persistence.log target global.auth-server.appLoggers.scriptLogLevel string \"INFO\" jans-auth_script.log level global.auth-server.appLoggers.scriptLogTarget string \"FILE\" jans-auth_script.log target global.auth-server.authEncKeys string \"RSA1_5 RSA-OAEP\" space-separated key algorithm for encryption (default to RSA1_5 RSA-OAEP ) global.auth-server.authServerServiceName string \"auth-server\" Name of the auth-server service. Please keep it as default. global.auth-server.authSigKeys string \"RS256 RS384 RS512 ES256 ES384 ES512 PS256 PS384 PS512\" space-separated key algorithm for signing (default to RS256 RS384 RS512 ES256 ES384 ES512 PS256 PS384 PS512 ) global.auth-server.cnCustomJavaOptions string \"\" passing custom java options to auth-server. Notice you do not need to pass in any loggers options as they are introduced below in appLoggers. DO NOT PASS JAVA_OPTIONS in envs. global.auth-server.enabled bool true Boolean flag to enable/disable auth-server chart. You should never set this to false. global.auth-server.ingress object {\"authServerEnabled\":true,\"authServerProtectedRegister\":false,\"authServerProtectedToken\":false,\"deviceCodeEnabled\":true,\"firebaseMessagingEnabled\":true,\"openidConfigEnabled\":true,\"u2fConfigEnabled\":true,\"uma2ConfigEnabled\":true,\"webdiscoveryEnabled\":true,\"webfingerEnabled\":true} Enable endpoints in either istio or nginx ingress depending on users choice global.auth-server.ingress.authServerEnabled bool true Enable Auth server endpoints /jans-auth global.auth-server.ingress.authServerProtectedRegister bool false Enable mTLS onn Auth server endpoint /jans-auth/restv1/register. Currently not working in Istio. global.auth-server.ingress.authServerProtectedToken bool false Enable mTLS on Auth server endpoint /jans-auth/restv1/token. Currently not working in Istio. global.auth-server.ingress.deviceCodeEnabled bool true Enable endpoint /device-code global.auth-server.ingress.firebaseMessagingEnabled bool true Enable endpoint /firebase-messaging-sw.js global.auth-server.ingress.openidConfigEnabled bool true Enable endpoint /.well-known/openid-configuration global.auth-server.ingress.u2fConfigEnabled bool true Enable endpoint /.well-known/fido-configuration global.auth-server.ingress.uma2ConfigEnabled bool true Enable endpoint /.well-known/uma2-configuration global.auth-server.ingress.webdiscoveryEnabled bool true Enable endpoint /.well-known/simple-web-discovery global.auth-server.ingress.webfingerEnabled bool true Enable endpoint /.well-known/webfinger global.auth-server.lockEnabled bool false Enable jans-lock as service running inside auth-server global.awsStorageType string \"io1\" Volume storage type if using AWS volumes. global.azureStorageAccountType string \"Standard_LRS\" Volume storage type if using Azure disks. global.azureStorageKind string \"Managed\" Azure storage kind if using Azure disks global.casa.appLoggers object {\"casaLogLevel\":\"INFO\",\"casaLogTarget\":\"STDOUT\",\"enableStdoutLogPrefix\":\"true\",\"timerLogLevel\":\"INFO\",\"timerLogTarget\":\"FILE\"} App loggers can be configured to define where the logs will be redirected to and the level of each in which it should be displayed. global.casa.appLoggers.casaLogLevel string \"INFO\" casa.log level global.casa.appLoggers.casaLogTarget string \"STDOUT\" casa.log target global.casa.appLoggers.enableStdoutLogPrefix string \"true\" Enable log prefixing which enables prepending the STDOUT logs with the file name. i.e casa ===> 2022-12-20 17:49:55,744 INFO global.casa.appLoggers.timerLogLevel string \"INFO\" casa timer log level global.casa.appLoggers.timerLogTarget string \"FILE\" casa timer log target global.casa.casaServiceName string \"casa\" Name of the casa service. Please keep it as default. global.casa.cnCustomJavaOptions string \"\" passing custom java options to casa. Notice you do not need to pass in any loggers options as they are introduced below in appLoggers. DO NOT PASS JAVA_OPTIONS in envs. global.casa.enabled bool true Boolean flag to enable/disable the casa chart. global.casa.ingress object {\"casaEnabled\":false} Enable endpoints in either istio or nginx ingress depending on users choice global.casa.ingress.casaEnabled bool false Enable casa endpoints /casa global.cloud.testEnviroment bool false Boolean flag if enabled will strip resources requests and limits from all services. global.cnCouchbasePasswordFile string \"/etc/jans/conf/couchbase_password\" Path to Couchbase password file global.cnCouchbaseSuperuserPasswordFile string \"/etc/jans/conf/couchbase_superuser_password\" Path to Couchbase superuser password file global.cnDocumentStoreType string \"DB\" Document store type to use for shibboleth files DB. global.cnGoogleApplicationCredentials string \"/etc/jans/conf/google-credentials.json\" Base64 encoded service account. The sa must have roles/secretmanager.admin to use Google secrets and roles/spanner.databaseUser to use Spanner. Leave as this is a sensible default. global.cnLdapCacertFile string \"/etc/certs/opendj.pem\" Path to OpenDJ CA cert file global.cnLdapCertFile string \"/etc/certs/opendj.crt\" Path to OpenDJ cert file global.cnLdapKeyFile string \"/etc/certs/opendj.key\" Path to OpenDJ key file global.cnLdapPasswordFile string \"/etc/jans/conf/ldap_password\" Path to LDAP password file global.cnLdapTruststoreFile string \"/etc/certs/opendj.pkcs12\" Path to OpenDJ truststore file global.cnLdapTruststorePasswordFile string \"/etc/jans/conf/ldap_truststore_password\" Path to LDAP truststore password file global.cnObExtSigningAlias string \"\" Open banking external signing AS Alias. This is a kid value.Used in SSA Validation, kid used while encoding a JWT sent to token URL i.e. XkwIzWy44xWSlcWnMiEc8iq9s2G global.cnObExtSigningJwksCrt string \"\" Open banking external signing jwks AS certificate authority string. Used in SSA Validation. This must be encoded using base64.. Used when .global.cnObExtSigningJwksUri is set. global.cnObExtSigningJwksKey string \"\" Open banking external signing jwks AS key string. Used in SSA Validation. This must be encoded using base64. Used when .global.cnObExtSigningJwksUri is set. global.cnObExtSigningJwksKeyPassPhrase string \"\" Open banking external signing jwks AS key passphrase to unlock provided key. This must be encoded using base64. Used when .global.cnObExtSigningJwksUri is set. global.cnObExtSigningJwksUri string \"\" Open banking external signing jwks uri. Used in SSA Validation. global.cnObStaticSigningKeyKid string \"\" Open banking signing AS kid to force the AS to use a specific signing key. i.e. Wy44xWSlcWnMiEc8iq9s2G global.cnObTransportAlias string \"\" Open banking transport Alias used inside the JVM. global.cnObTransportCrt string \"\" Open banking AS transport crt. Used in SSA Validation. This must be encoded using base64. global.cnObTransportKey string \"\" Open banking AS transport key. Used in SSA Validation. This must be encoded using base64. global.cnObTransportKeyPassPhrase string \"\" Open banking AS transport key passphrase to unlock AS transport key. This must be encoded using base64. global.cnObTransportTrustStore string \"\" Open banking AS transport truststore crt. This is normally generated from the OB issuing CA, OB Root CA and Signing CA. Used when .global.cnObExtSigningJwksUri is set. Used in SSA Validation. This must be encoded using base64. global.cnPersistenceType string \"sql\" Persistence backend to run Gluu with ldap global.cnPrometheusPort string \"\" Port used by Prometheus JMX agent (default to empty string). To enable Prometheus JMX agent, set the value to a number. global.cnSqlPasswordFile string \"/etc/jans/conf/sql_password\" Path to SQL password file global.config-api.adminUiAppLoggers.adminUiAuditLogLevel string \"INFO\" config-api admin-ui plugin audit log level global.config-api.adminUiAppLoggers.adminUiAuditLogTarget string \"FILE\" config-api admin-ui plugin audit log target global.config-api.adminUiAppLoggers.adminUiLogLevel string \"INFO\" config-api admin-ui plugin log target global.config-api.adminUiAppLoggers.adminUiLogTarget string \"FILE\" config-api admin-ui plugin log level global.config-api.adminUiAppLoggers.enableStdoutLogPrefix string \"true\" Enable log prefixing which enables prepending the STDOUT logs with the file name. i.e config-api_persistence ===> 2022-12-20 17:49:55,744 INFO global.config-api.appLoggers object {\"configApiLogLevel\":\"INFO\",\"configApiLogTarget\":\"STDOUT\",\"enableStdoutLogPrefix\":\"true\",\"ldapStatsLogLevel\":\"INFO\",\"ldapStatsLogTarget\":\"FILE\",\"persistenceDurationLogLevel\":\"INFO\",\"persistenceDurationLogTarget\":\"FILE\",\"persistenceLogLevel\":\"INFO\",\"persistenceLogTarget\":\"FILE\",\"scriptLogLevel\":\"INFO\",\"scriptLogTarget\":\"FILE\"} App loggers can be configured to define where the logs will be redirected to and the level of each in which it should be displayed. global.config-api.appLoggers.configApiLogLevel string \"INFO\" configapi.log level global.config-api.appLoggers.configApiLogTarget string \"STDOUT\" configapi.log target global.config-api.appLoggers.enableStdoutLogPrefix string \"true\" Enable log prefixing which enables prepending the STDOUT logs with the file name. i.e config-api_persistence ===> 2022-12-20 17:49:55,744 INFO global.config-api.appLoggers.ldapStatsLogLevel string \"INFO\" config-api_persistence_ldap_statistics.log level global.config-api.appLoggers.ldapStatsLogTarget string \"FILE\" config-api_persistence_ldap_statistics.log target global.config-api.appLoggers.persistenceDurationLogLevel string \"INFO\" config-api_persistence_duration.log level global.config-api.appLoggers.persistenceDurationLogTarget string \"FILE\" config-api_persistence_duration.log target global.config-api.appLoggers.persistenceLogLevel string \"INFO\" config-api_persistence.log level global.config-api.appLoggers.persistenceLogTarget string \"FILE\" config-api_persistence.log target global.config-api.appLoggers.scriptLogLevel string \"INFO\" config-api_script.log level global.config-api.appLoggers.scriptLogTarget string \"FILE\" config-api_script.log target global.config-api.cnCustomJavaOptions string \"\" passing custom java options to config-api. Notice you do not need to pass in any loggers options as they are introduced below in appLoggers. DO NOT PASS JAVA_OPTIONS in envs. global.config-api.configApiServerServiceName string \"config-api\" Name of the config-api service. Please keep it as default. global.config-api.enabled bool true Boolean flag to enable/disable the config-api chart. global.config-api.ingress object {\"configApiEnabled\":true} Enable endpoints in either istio or nginx ingress depending on users choice global.config-api.plugins string \"admin-ui,fido2,scim,user-mgt\" Comma-separated values of enabled plugins (supported plugins are \"admin-ui\",\"fido2\",\"scim\",\"user-mgt\",\"jans-link\",\"kc-saml\") global.config.enabled bool true Boolean flag to enable/disable the configuration chart. This normally should never be false global.configAdapterName string \"kubernetes\" The config backend adapter that will hold Gluu configuration layer. aws global.configSecretAdapter string \"kubernetes\" The config backend adapter that will hold Gluu secret layer. vault global.distribution string \"default\" Gluu distributions supported are: default global.fido2.appLoggers object {\"enableStdoutLogPrefix\":\"true\",\"fido2LogLevel\":\"INFO\",\"fido2LogTarget\":\"STDOUT\",\"persistenceDurationLogLevel\":\"INFO\",\"persistenceDurationLogTarget\":\"FILE\",\"persistenceLogLevel\":\"INFO\",\"persistenceLogTarget\":\"FILE\",\"scriptLogLevel\":\"INFO\",\"scriptLogTarget\":\"FILE\"} App loggers can be configured to define where the logs will be redirected to and the level of each in which it should be displayed. global.fido2.appLoggers.enableStdoutLogPrefix string \"true\" Enable log prefixing which enables prepending the STDOUT logs with the file name. i.e fido2 ===> 2022-12-20 17:49:55,744 INFO global.fido2.appLoggers.fido2LogLevel string \"INFO\" fido2.log level global.fido2.appLoggers.fido2LogTarget string \"STDOUT\" fido2.log target global.fido2.appLoggers.persistenceDurationLogLevel string \"INFO\" fido2_persistence_duration.log level global.fido2.appLoggers.persistenceDurationLogTarget string \"FILE\" fido2_persistence_duration.log target global.fido2.appLoggers.persistenceLogLevel string \"INFO\" fido2_persistence.log level global.fido2.appLoggers.persistenceLogTarget string \"FILE\" fido2_persistence.log target global.fido2.appLoggers.scriptLogLevel string \"INFO\" fido2_script.log level global.fido2.appLoggers.scriptLogTarget string \"FILE\" fido2_script.log target global.fido2.cnCustomJavaOptions string \"\" passing custom java options to fido2. Notice you do not need to pass in any loggers options as they are introduced below in appLoggers. DO NOT PASS JAVA_OPTIONS in envs. global.fido2.enabled bool true Boolean flag to enable/disable the fido2 chart. global.fido2.fido2ServiceName string \"fido2\" Name of the fido2 service. Please keep it as default. global.fido2.ingress object {\"fido2ConfigEnabled\":false,\"fido2Enabled\":false} Enable endpoints in either istio or nginx ingress depending on users choice global.fido2.ingress.fido2ConfigEnabled bool false Enable endpoint /.well-known/fido2-configuration global.fido2.ingress.fido2Enabled bool false Enable endpoint /jans-fido2 global.fqdn string \"demoexample.gluu.org\" Fully qualified domain name to be used for Gluu installation. This address will be used to reach Gluu services. global.gcePdStorageType string \"pd-standard\" GCE storage kind if using Google disks global.isFqdnRegistered bool false Boolean flag to enable mapping global.lbIp to global.fqdn inside pods on clouds that provide static ip for load balancers. On cloud that provide only addresses to the LB this flag will enable a script to actively scan config.configmap.lbAddr and update the hosts file inside the pods automatically. global.istio.additionalAnnotations object {} Additional annotations that will be added across the gateway in the format of global.istio.additionalLabels object {} Additional labels that will be added across the gateway in the format of global.istio.enabled bool false Boolean flag that enables using istio side-cars with Gluu services. global.istio.gateways list [] Override the gateway that can be created by default. This is used when istio ingress has already been setup and the gateway exists. global.istio.ingress bool false Boolean flag that enables using istio gateway for Gluu. This assumes istio ingress is installed and hence the LB is available. global.istio.namespace string \"istio-system\" The namespace istio is deployed in. The is normally istio-system. global.jobTtlSecondsAfterFinished int 300 https://kubernetes.io/docs/concepts/workloads/controllers/ttlafterfinished/ global.kc-scheduler.enabled bool false Boolean flag to enable/disable the kc-scheduler cronjob chart. global.kcAdminCredentialsFile string \"/etc/jans/conf/kc_admin_creds\" Path to file contains Keycloak admin credentials (username and password) global.kcDbPasswordFile string \"/etc/jans/conf/kc_db_password\" Path to file contains password for database access global.lbIp string \"22.22.22.22\" The Loadbalancer IP created by nginx or istio on clouds that provide static IPs. This is not needed if global.fqdn is globally resolvable. global.link.appLoggers object {\"enableStdoutLogPrefix\":\"true\",\"ldapStatsLogLevel\":\"INFO\",\"ldapStatsLogTarget\":\"FILE\",\"linkLogLevel\":\"INFO\",\"linkLogTarget\":\"STDOUT\",\"persistenceDurationLogLevel\":\"INFO\",\"persistenceDurationLogTarget\":\"FILE\",\"persistenceLogLevel\":\"INFO\",\"persistenceLogTarget\":\"FILE\",\"scriptLogLevel\":\"INFO\",\"scriptLogTarget\":\"FILE\"} App loggers can be configured to define where the logs will be redirected to and the level of each in which it should be displayed. global.link.appLoggers.enableStdoutLogPrefix string \"true\" Enable log prefixing which enables prepending the STDOUT logs with the file name. i.e link-persistence ===> 2022-12-20 17:49:55,744 INFO global.link.appLoggers.ldapStatsLogLevel string \"INFO\" cacherefresh_persistence_ldap_statistics.log level global.link.appLoggers.ldapStatsLogTarget string \"FILE\" cacherefresh_persistence_ldap_statistics.log target global.link.appLoggers.linkLogLevel string \"INFO\" cacherefresh.log level global.link.appLoggers.linkLogTarget string \"STDOUT\" cacherefresh.log target global.link.appLoggers.persistenceDurationLogLevel string \"INFO\" cacherefresh_persistence_duration.log level global.link.appLoggers.persistenceDurationLogTarget string \"FILE\" cacherefresh_persistence_duration.log target global.link.appLoggers.persistenceLogLevel string \"INFO\" cacherefresh_persistence.log level global.link.appLoggers.persistenceLogTarget string \"FILE\" cacherefresh_persistence.log target global.link.appLoggers.scriptLogLevel string \"INFO\" cacherefresh_script.log level global.link.appLoggers.scriptLogTarget string \"FILE\" cacherefresh_script.log target global.link.cnCustomJavaOptions string \"\" passing custom java options to link. Notice you do not need to pass in any loggers options as they are introduced below in appLoggers. DO NOT PASS JAVA_OPTIONS in envs. global.link.enabled bool false Boolean flag to enable/disable the link chart. global.link.ingress object {\"linkEnabled\":true} Enable endpoints in either istio or nginx ingress depending on users choice global.link.linkServiceName string \"link\" Name of the link service. Please keep it as default. global.nginx-ingress.enabled bool true Boolean flag to enable/disable the nginx-ingress definitions chart. global.opendj.enabled bool false Boolean flag to enable/disable the OpenDJ chart. global.opendj.ldapServiceName string \"opendj\" Name of the OpenDJ service. Please keep it as default. global.persistence.enabled bool true Boolean flag to enable/disable the persistence chart. global.saml.cnCustomJavaOptions string \"\" passing custom java options to saml. DO NOT PASS JAVA_OPTIONS in envs. global.saml.enabled bool false Boolean flag to enable/disable the saml chart. global.saml.ingress object {\"samlEnabled\":false} Enable endpoints in either istio or nginx ingress depending on users choice global.saml.samlServiceName string \"saml\" Name of the saml service. Please keep it as default. global.scim.appLoggers object {\"enableStdoutLogPrefix\":\"true\",\"ldapStatsLogLevel\":\"INFO\",\"ldapStatsLogTarget\":\"FILE\",\"persistenceDurationLogLevel\":\"INFO\",\"persistenceDurationLogTarget\":\"FILE\",\"persistenceLogLevel\":\"INFO\",\"persistenceLogTarget\":\"FILE\",\"scimLogLevel\":\"INFO\",\"scimLogTarget\":\"STDOUT\",\"scriptLogLevel\":\"INFO\",\"scriptLogTarget\":\"FILE\"} App loggers can be configured to define where the logs will be redirected to and the level of each in which it should be displayed. global.scim.appLoggers.enableStdoutLogPrefix string \"true\" Enable log prefixing which enables prepending the STDOUT logs with the file name. i.e jans-scim ===> 2022-12-20 17:49:55,744 INFO global.scim.appLoggers.ldapStatsLogLevel string \"INFO\" jans-scim_persistence_ldap_statistics.log level global.scim.appLoggers.ldapStatsLogTarget string \"FILE\" jans-scim_persistence_ldap_statistics.log target global.scim.appLoggers.persistenceDurationLogLevel string \"INFO\" jans-scim_persistence_duration.log level global.scim.appLoggers.persistenceDurationLogTarget string \"FILE\" jans-scim_persistence_duration.log target global.scim.appLoggers.persistenceLogLevel string \"INFO\" jans-scim_persistence.log level global.scim.appLoggers.persistenceLogTarget string \"FILE\" jans-scim_persistence.log target global.scim.appLoggers.scimLogLevel string \"INFO\" jans-scim.log level global.scim.appLoggers.scimLogTarget string \"STDOUT\" jans-scim.log target global.scim.appLoggers.scriptLogLevel string \"INFO\" jans-scim_script.log level global.scim.appLoggers.scriptLogTarget string \"FILE\" jans-scim_script.log target global.scim.cnCustomJavaOptions string \"\" passing custom java options to scim. Notice you do not need to pass in any loggers options as they are introduced below in appLoggers. DO NOT PASS JAVA_OPTIONS in envs. global.scim.enabled bool true Boolean flag to enable/disable the SCIM chart. global.scim.ingress object {\"scimConfigEnabled\":false,\"scimEnabled\":false} Enable endpoints in either istio or nginx ingress depending on users choice global.scim.ingress.scimConfigEnabled bool false Enable endpoint /.well-known/scim-configuration global.scim.ingress.scimEnabled bool false Enable SCIM endpoints /jans-scim global.scim.scimServiceName string \"scim\" Name of the scim service. Please keep it as default. global.storageClass object {\"allowVolumeExpansion\":true,\"allowedTopologies\":[],\"mountOptions\":[\"debug\"],\"parameters\":{},\"provisioner\":\"microk8s.io/hostpath\",\"reclaimPolicy\":\"Retain\",\"volumeBindingMode\":\"WaitForFirstConsumer\"} StorageClass section for OpenDJ charts. This is not currently used by the openbanking distribution. You may specify custom parameters as needed. global.storageClass.parameters object {} parameters: fsType: \"\" kind: \"\" pool: \"\" storageAccountType: \"\" type: \"\" global.usrEnvs object {\"normal\":{},\"secret\":{}} Add custom normal and secret envs to the service. Envs defined in global.userEnvs will be globally available to all services global.usrEnvs.normal object {} Add custom normal envs to the service. variable1: value1 global.usrEnvs.secret object {} Add custom secret envs to the service. variable1: value1 installer-settings object {\"acceptLicense\":\"\",\"aws\":{\"arn\":{\"arnAcmCert\":\"\",\"enabled\":\"\"},\"lbType\":\"\",\"vpcCidr\":\"0.0.0.0/0\"},\"confirmSettings\":false,\"couchbase\":{\"backup\":{\"fullSchedule\":\"\",\"incrementalSchedule\":\"\",\"retentionTime\":\"\",\"storageSize\":\"\"},\"clusterName\":\"\",\"commonName\":\"\",\"customFileOverride\":\"\",\"install\":\"\",\"lowResourceInstall\":\"\",\"namespace\":\"\",\"subjectAlternativeName\":\"\",\"totalNumberOfExpectedTransactionsPerSec\":\"\",\"totalNumberOfExpectedUsers\":\"\",\"volumeType\":\"\"},\"currentVersion\":\"\",\"google\":{\"useSecretManager\":\"\"},\"images\":{\"edit\":\"\"},\"ldap\":{\"backup\":{\"fullSchedule\":\"\"}},\"namespace\":\"\",\"nginxIngress\":{\"namespace\":\"\",\"releaseName\":\"\"},\"nodes\":{\"ips\":\"\",\"names\":\"\",\"zones\":\"\"},\"openbanking\":{\"cnObTransportTrustStoreP12password\":\"\",\"hasCnObTransportTrustStore\":false},\"postgres\":{\"install\":\"\",\"namespace\":\"\"},\"redis\":{\"install\":\"\",\"namespace\":\"\"},\"releaseName\":\"\",\"sql\":{\"install\":\"\",\"namespace\":\"\"},\"volumeProvisionStrategy\":\"\"} Only used by the installer. These settings do not affect nor are used by the chart kc-scheduler object {\"additionalAnnotations\":{},\"additionalLabels\":{},\"customScripts\":[],\"dnsConfig\":{},\"dnsPolicy\":\"\",\"image\":{\"pullPolicy\":\"IfNotPresent\",\"pullSecrets\":[],\"repository\":\"ghcr.io/janssenproject/jans/kc-scheduler\",\"tag\":\"1.1.6_dev\"},\"interval\":10,\"lifecycle\":{},\"resources\":{\"limits\":{\"cpu\":\"300m\",\"memory\":\"300Mi\"},\"requests\":{\"cpu\":\"300m\",\"memory\":\"300Mi\"}},\"usrEnvs\":{\"normal\":{},\"secret\":{}},\"volumeMounts\":[],\"volumes\":[]} Responsible for synchronizing Keycloak SAML clients kc-scheduler.additionalAnnotations object {} Additional annotations that will be added across the gateway in the format of kc-scheduler.additionalLabels object {} Additional labels that will be added across the gateway in the format of kc-scheduler.customScripts list [] Add custom scripts that have been mounted to run before the entrypoint. - /tmp/custom.sh - /tmp/custom2.sh kc-scheduler.dnsConfig object {} Add custom dns config kc-scheduler.dnsPolicy string \"\" Add custom dns policy kc-scheduler.image.pullPolicy string \"IfNotPresent\" Image pullPolicy to use for deploying. kc-scheduler.image.pullSecrets list [] Image Pull Secrets kc-scheduler.image.repository string \"ghcr.io/janssenproject/jans/kc-scheduler\" Image to use for deploying. kc-scheduler.image.tag string \"1.1.6_dev\" Image tag to use for deploying. kc-scheduler.interval int 10 Interval of running the scheduler (in minutes) kc-scheduler.resources object {\"limits\":{\"cpu\":\"300m\",\"memory\":\"300Mi\"},\"requests\":{\"cpu\":\"300m\",\"memory\":\"300Mi\"}} Resource specs. kc-scheduler.resources.limits.cpu string \"300m\" CPU limit. kc-scheduler.resources.limits.memory string \"300Mi\" Memory limit. kc-scheduler.resources.requests.cpu string \"300m\" CPU request. kc-scheduler.resources.requests.memory string \"300Mi\" Memory request. kc-scheduler.usrEnvs object {\"normal\":{},\"secret\":{}} Add custom normal and secret envs to the service kc-scheduler.usrEnvs.normal object {} Add custom normal envs to the service variable1: value1 kc-scheduler.usrEnvs.secret object {} Add custom secret envs to the service variable1: value1 kc-scheduler.volumeMounts list [] Configure any additional volumesMounts that need to be attached to the containers kc-scheduler.volumes list [] Configure any additional volumes that need to be attached to the pod link object {\"additionalAnnotations\":{},\"additionalLabels\":{},\"customScripts\":[],\"dnsConfig\":{},\"dnsPolicy\":\"\",\"hpa\":{\"behavior\":{},\"enabled\":true,\"maxReplicas\":10,\"metrics\":[],\"minReplicas\":1,\"targetCPUUtilizationPercentage\":50},\"image\":{\"pullPolicy\":\"IfNotPresent\",\"pullSecrets\":[],\"repository\":\"ghcr.io/janssenproject/jans/link\",\"tag\":\"1.1.6_dev\"},\"lifecycle\":{},\"livenessProbe\":{\"exec\":{\"command\":[\"python3\",\"/app/scripts/healthcheck.py\"]},\"initialDelaySeconds\":30,\"periodSeconds\":30,\"timeoutSeconds\":5},\"pdb\":{\"enabled\":true,\"maxUnavailable\":\"90%\"},\"readinessProbe\":{\"exec\":{\"command\":[\"python3\",\"/app/scripts/healthcheck.py\"]},\"initialDelaySeconds\":25,\"periodSeconds\":25,\"timeoutSeconds\":5},\"replicas\":1,\"resources\":{\"limits\":{\"cpu\":\"500m\",\"memory\":\"1200Mi\"},\"requests\":{\"cpu\":\"500m\",\"memory\":\"1200Mi\"}},\"topologySpreadConstraints\":{},\"usrEnvs\":{\"normal\":{},\"secret\":{}},\"volumeMounts\":[],\"volumes\":[]} Link. link.additionalAnnotations object {} Additional annotations that will be added across the gateway in the format of link.additionalLabels object {} Additional labels that will be added across the gateway in the format of link.customScripts list [] Add custom scripts that have been mounted to run before the entrypoint. - /tmp/custom.sh - /tmp/custom2.sh link.dnsConfig object {} Add custom dns config link.dnsPolicy string \"\" Add custom dns policy link.hpa object {\"behavior\":{},\"enabled\":true,\"maxReplicas\":10,\"metrics\":[],\"minReplicas\":1,\"targetCPUUtilizationPercentage\":50} Configure the HorizontalPodAutoscaler link.hpa.behavior object {} Scaling Policies link.hpa.metrics list [] metrics if targetCPUUtilizationPercentage is not set link.image.pullPolicy string \"IfNotPresent\" Image pullPolicy to use for deploying. link.image.pullSecrets list [] Image Pull Secrets link.image.repository string \"ghcr.io/janssenproject/jans/link\" Image to use for deploying. link.image.tag string \"1.1.6_dev\" Image tag to use for deploying. link.livenessProbe object {\"exec\":{\"command\":[\"python3\",\"/app/scripts/healthcheck.py\"]},\"initialDelaySeconds\":30,\"periodSeconds\":30,\"timeoutSeconds\":5} Configure the liveness healthcheck for the auth server if needed. link.livenessProbe.exec object {\"command\":[\"python3\",\"/app/scripts/healthcheck.py\"]} http liveness probe endpoint link.pdb object {\"enabled\":true,\"maxUnavailable\":\"90%\"} Configure the PodDisruptionBudget link.readinessProbe.exec object {\"command\":[\"python3\",\"/app/scripts/healthcheck.py\"]} http readiness probe endpoint link.replicas int 1 Service replica number. link.resources object {\"limits\":{\"cpu\":\"500m\",\"memory\":\"1200Mi\"},\"requests\":{\"cpu\":\"500m\",\"memory\":\"1200Mi\"}} Resource specs. link.resources.limits.cpu string \"500m\" CPU limit. link.resources.limits.memory string \"1200Mi\" Memory limit. This value is used to calculate memory allocation for Java. Currently it only supports Mi . Please refrain from using other units. link.resources.requests.cpu string \"500m\" CPU request. link.resources.requests.memory string \"1200Mi\" Memory request. link.topologySpreadConstraints object {} Configure the topology spread constraints. Notice this is a map NOT a list as in the upstream API https://kubernetes.io/docs/concepts/scheduling-eviction/topology-spread-constraints/ link.usrEnvs object {\"normal\":{},\"secret\":{}} Add custom normal and secret envs to the service link.usrEnvs.normal object {} Add custom normal envs to the service variable1: value1 link.usrEnvs.secret object {} Add custom secret envs to the service variable1: value1 link.volumeMounts list [] Configure any additional volumesMounts that need to be attached to the containers link.volumes list [] Configure any additional volumes that need to be attached to the pod nginx-ingress object {\"certManager\":{\"certificate\":{\"enabled\":false,\"issuerGroup\":\"cert-manager.io\",\"issuerKind\":\"ClusterIssuer\",\"issuerName\":\"\"}},\"ingress\":{\"additionalAnnotations\":{},\"additionalLabels\":{},\"adminUiAdditionalAnnotations\":{},\"adminUiLabels\":{},\"authServerAdditionalAnnotations\":{},\"authServerLabels\":{},\"authServerProtectedRegisterAdditionalAnnotations\":{},\"authServerProtectedRegisterLabels\":{},\"authServerProtectedTokenAdditionalAnnotations\":{},\"authServerProtectedTokenLabels\":{},\"casaAdditionalAnnotations\":{},\"casaLabels\":{},\"configApiAdditionalAnnotations\":{},\"configApiLabels\":{},\"deviceCodeAdditionalAnnotations\":{},\"deviceCodeLabels\":{},\"fido2AdditionalAnnotations\":{},\"fido2ConfigAdditionalAnnotations\":{},\"fido2ConfigLabels\":{},\"fido2Labels\":{},\"firebaseMessagingAdditionalAnnotations\":{},\"firebaseMessagingLabels\":{},\"hosts\":[\"demoexample.gluu.org\"],\"ingressClassName\":\"nginx\",\"openidAdditionalAnnotations\":{},\"openidConfigLabels\":{},\"path\":\"/\",\"samlAdditionalAnnotations\":{},\"samlLabels\":{},\"scimAdditionalAnnotations\":{},\"scimConfigAdditionalAnnotations\":{},\"scimConfigLabels\":{},\"scimLabels\":{},\"tls\":[{\"hosts\":[\"demoexample.gluu.org\"],\"secretName\":\"tls-certificate\"}],\"u2fAdditionalAnnotations\":{},\"u2fConfigLabels\":{},\"uma2AdditionalAnnotations\":{},\"uma2ConfigLabels\":{},\"webdiscoveryAdditionalAnnotations\":{},\"webdiscoveryLabels\":{},\"webfingerAdditionalAnnotations\":{},\"webfingerLabels\":{}}} Nginx ingress definitions chart nginx-ingress.ingress.additionalAnnotations object {} Additional annotations that will be added across all ingress definitions in the format of {cert-manager.io/issuer: \"letsencrypt-prod\"} Enable client certificate authentication nginx.ingress.kubernetes.io/auth-tls-verify-client: \"optional\" Create the secret containing the trusted ca certificates nginx.ingress.kubernetes.io/auth-tls-secret: \"gluu/tls-certificate\" Specify the verification depth in the client certificates chain nginx.ingress.kubernetes.io/auth-tls-verify-depth: \"1\" Specify if certificates are passed to upstream server nginx.ingress.kubernetes.io/auth-tls-pass-certificate-to-upstream: \"true\" nginx-ingress.ingress.additionalLabels object {} Additional labels that will be added across all ingress definitions in the format of nginx-ingress.ingress.adminUiAdditionalAnnotations object {} openid-configuration ingress resource additional annotations. nginx-ingress.ingress.adminUiLabels object {} Admin UI ingress resource labels. key app is taken. nginx-ingress.ingress.authServerAdditionalAnnotations object {} Auth server ingress resource additional annotations. nginx-ingress.ingress.authServerLabels object {} Auth server ingress resource labels. key app is taken nginx-ingress.ingress.authServerProtectedRegisterAdditionalAnnotations object {} Auth server protected register ingress resource additional annotations. nginx-ingress.ingress.authServerProtectedRegisterLabels object {} Auth server protected token ingress resource labels. key app is taken nginx-ingress.ingress.authServerProtectedTokenAdditionalAnnotations object {} Auth server protected token ingress resource additional annotations. nginx-ingress.ingress.authServerProtectedTokenLabels object {} Auth server protected token ingress resource labels. key app is taken nginx-ingress.ingress.casaAdditionalAnnotations object {} Casa ingress resource additional annotations. nginx-ingress.ingress.casaLabels object {} Casa ingress resource labels. key app is taken nginx-ingress.ingress.configApiAdditionalAnnotations object {} ConfigAPI ingress resource additional annotations. nginx-ingress.ingress.configApiLabels object {} configAPI ingress resource labels. key app is taken nginx-ingress.ingress.deviceCodeAdditionalAnnotations object {} device-code ingress resource additional annotations. nginx-ingress.ingress.deviceCodeLabels object {} device-code ingress resource labels. key app is taken nginx-ingress.ingress.fido2AdditionalAnnotations object {} fido2 ingress resource additional annotations. nginx-ingress.ingress.fido2ConfigAdditionalAnnotations object {} fido2 config ingress resource additional annotations. nginx-ingress.ingress.fido2ConfigLabels object {} fido2 config ingress resource labels. key app is taken nginx-ingress.ingress.fido2Labels object {} fido2 ingress resource labels. key app is taken nginx-ingress.ingress.firebaseMessagingAdditionalAnnotations object {} Firebase Messaging ingress resource additional annotations. nginx-ingress.ingress.firebaseMessagingLabels object {} Firebase Messaging ingress resource labels. key app is taken nginx-ingress.ingress.openidAdditionalAnnotations object {} openid-configuration ingress resource additional annotations. nginx-ingress.ingress.openidConfigLabels object {} openid-configuration ingress resource labels. key app is taken nginx-ingress.ingress.samlAdditionalAnnotations object {} SAML ingress resource additional annotations. nginx-ingress.ingress.samlLabels object {} SAML config ingress resource labels. key app is taken nginx-ingress.ingress.scimAdditionalAnnotations object {} SCIM ingress resource additional annotations. nginx-ingress.ingress.scimConfigAdditionalAnnotations object {} SCIM config ingress resource additional annotations. nginx-ingress.ingress.scimConfigLabels object {} SCIM config ingress resource labels. key app is taken nginx-ingress.ingress.scimLabels object {} SCIM config ingress resource labels. key app is taken nginx-ingress.ingress.tls list [{\"hosts\":[\"demoexample.gluu.org\"],\"secretName\":\"tls-certificate\"}] Secrets holding HTTPS CA cert and key. nginx-ingress.ingress.u2fAdditionalAnnotations object {} u2f config ingress resource additional annotations. nginx-ingress.ingress.u2fConfigLabels object {} u2f config ingress resource labels. key app is taken nginx-ingress.ingress.uma2AdditionalAnnotations object {} uma2 config ingress resource additional annotations. nginx-ingress.ingress.uma2ConfigLabels object {} uma2 config ingress resource labels. key app is taken nginx-ingress.ingress.webdiscoveryAdditionalAnnotations object {} webdiscovery ingress resource additional annotations. nginx-ingress.ingress.webdiscoveryLabels object {} webdiscovery ingress resource labels. key app is taken nginx-ingress.ingress.webfingerAdditionalAnnotations object {} webfinger ingress resource additional annotations. nginx-ingress.ingress.webfingerLabels object {} webfinger ingress resource labels. key app is taken opendj object {\"additionalAnnotations\":{},\"additionalLabels\":{},\"backup\":{\"cronJobSchedule\":\"*/59 * * * *\",\"enabled\":true},\"customScripts\":[],\"dnsConfig\":{},\"dnsPolicy\":\"\",\"hpa\":{\"behavior\":{},\"enabled\":true,\"maxReplicas\":10,\"metrics\":[],\"minReplicas\":1,\"targetCPUUtilizationPercentage\":50},\"image\":{\"pullPolicy\":\"IfNotPresent\",\"pullSecrets\":[],\"repository\":\"gluufederation/opendj\",\"tag\":\"5.0.0_dev\"},\"lifecycle\":{\"preStop\":{\"exec\":{\"command\":[\"/bin/sh\",\"-c\",\"python3 /app/scripts/deregister_peer.py 1>&/proc/1/fd/1\"]}}},\"livenessProbe\":{\"exec\":{\"command\":[\"python3\",\"/app/scripts/healthcheck.py\"]},\"failureThreshold\":20,\"initialDelaySeconds\":30,\"periodSeconds\":30,\"timeoutSeconds\":5},\"pdb\":{\"enabled\":true,\"maxUnavailable\":1},\"persistence\":{\"size\":\"5Gi\"},\"ports\":{\"tcp-admin\":{\"nodePort\":\"\",\"port\":4444,\"protocol\":\"TCP\",\"targetPort\":4444},\"tcp-ldap\":{\"nodePort\":\"\",\"port\":1389,\"protocol\":\"TCP\",\"targetPort\":1389},\"tcp-ldaps\":{\"nodePort\":\"\",\"port\":1636,\"protocol\":\"TCP\",\"targetPort\":1636},\"tcp-repl\":{\"nodePort\":\"\",\"port\":8989,\"protocol\":\"TCP\",\"targetPort\":8989},\"tcp-serf\":{\"nodePort\":\"\",\"port\":7946,\"protocol\":\"TCP\",\"targetPort\":7946},\"udp-serf\":{\"nodePort\":\"\",\"port\":7946,\"protocol\":\"UDP\",\"targetPort\":7946}},\"readinessProbe\":{\"failureThreshold\":20,\"initialDelaySeconds\":60,\"periodSeconds\":25,\"tcpSocket\":{\"port\":1636},\"timeoutSeconds\":5},\"replicas\":1,\"resources\":{\"limits\":{\"cpu\":\"1500m\",\"memory\":\"2000Mi\"},\"requests\":{\"cpu\":\"1500m\",\"memory\":\"2000Mi\"}},\"topologySpreadConstraints\":{},\"usrEnvs\":{\"normal\":{},\"secret\":{}},\"volumeMounts\":[],\"volumes\":[]} OpenDJ is a directory server which implements a wide range of Lightweight Directory Access Protocol and related standards, including full compliance with LDAPv3 but also support for Directory Service Markup Language (DSMLv2).Written in Java, OpenDJ offers multi-master replication, access control, and many extensions. opendj.additionalAnnotations object {} Additional annotations that will be added across the gateway in the format of opendj.additionalLabels object {} Additional labels that will be added across the gateway in the format of opendj.backup object {\"cronJobSchedule\":\"*/59 * * * *\",\"enabled\":true} Configure ldap backup cronjob opendj.customScripts list [] Add custom scripts that have been mounted to run before the entrypoint. - /tmp/custom.sh - /tmp/custom2.sh opendj.dnsConfig object {} Add custom dns config opendj.dnsPolicy string \"\" Add custom dns policy opendj.hpa object {\"behavior\":{},\"enabled\":true,\"maxReplicas\":10,\"metrics\":[],\"minReplicas\":1,\"targetCPUUtilizationPercentage\":50} Configure the HorizontalPodAutoscaler opendj.hpa.behavior object {} Scaling Policies opendj.hpa.metrics list [] metrics if targetCPUUtilizationPercentage is not set opendj.image.pullPolicy string \"IfNotPresent\" Image pullPolicy to use for deploying. opendj.image.pullSecrets list [] Image Pull Secrets opendj.image.repository string \"gluufederation/opendj\" Image to use for deploying. opendj.image.tag string \"5.0.0_dev\" Image tag to use for deploying. opendj.livenessProbe object {\"exec\":{\"command\":[\"python3\",\"/app/scripts/healthcheck.py\"]},\"failureThreshold\":20,\"initialDelaySeconds\":30,\"periodSeconds\":30,\"timeoutSeconds\":5} Configure the liveness healthcheck for OpenDJ if needed. https://github.com/GluuFederation/docker-opendj/blob/master/scripts/healthcheck.py opendj.livenessProbe.exec object {\"command\":[\"python3\",\"/app/scripts/healthcheck.py\"]} Executes the python3 healthcheck. opendj.pdb object {\"enabled\":true,\"maxUnavailable\":1} Configure the PodDisruptionBudget opendj.persistence.size string \"5Gi\" OpenDJ volume size opendj.readinessProbe object {\"failureThreshold\":20,\"initialDelaySeconds\":60,\"periodSeconds\":25,\"tcpSocket\":{\"port\":1636},\"timeoutSeconds\":5} Configure the readiness healthcheck for OpenDJ if needed. https://github.com/GluuFederation/docker-opendj/blob/master/scripts/healthcheck.py opendj.replicas int 1 Service replica number. opendj.resources object {\"limits\":{\"cpu\":\"1500m\",\"memory\":\"2000Mi\"},\"requests\":{\"cpu\":\"1500m\",\"memory\":\"2000Mi\"}} Resource specs. opendj.resources.limits.cpu string \"1500m\" CPU limit. opendj.resources.limits.memory string \"2000Mi\" Memory limit. opendj.resources.requests.cpu string \"1500m\" CPU request. opendj.resources.requests.memory string \"2000Mi\" Memory request. opendj.topologySpreadConstraints object {} Configure the topology spread constraints. Notice this is a map NOT a list as in the upstream API https://kubernetes.io/docs/concepts/scheduling-eviction/topology-spread-constraints/ opendj.usrEnvs object {\"normal\":{},\"secret\":{}} Add custom normal and secret envs to the service opendj.usrEnvs.normal object {} Add custom normal envs to the service variable1: value1 opendj.usrEnvs.secret object {} Add custom secret envs to the service variable1: value1 opendj.volumeMounts list [] Configure any additional volumesMounts that need to be attached to the containers opendj.volumes list [] Configure any additional volumes that need to be attached to the pod persistence object {\"additionalAnnotations\":{},\"additionalLabels\":{},\"customScripts\":[],\"dnsConfig\":{},\"dnsPolicy\":\"\",\"image\":{\"pullPolicy\":\"IfNotPresent\",\"pullSecrets\":[],\"repository\":\"ghcr.io/janssenproject/jans/persistence-loader\",\"tag\":\"1.1.6_dev\"},\"lifecycle\":{},\"resources\":{\"limits\":{\"cpu\":\"300m\",\"memory\":\"300Mi\"},\"requests\":{\"cpu\":\"300m\",\"memory\":\"300Mi\"}},\"usrEnvs\":{\"normal\":{},\"secret\":{}},\"volumeMounts\":[],\"volumes\":[]} Job to generate data and initial config for Gluu Server persistence layer. persistence.additionalAnnotations object {} Additional annotations that will be added across the gateway in the format of persistence.additionalLabels object {} Additional labels that will be added across the gateway in the format of persistence.customScripts list [] Add custom scripts that have been mounted to run before the entrypoint. - /tmp/custom.sh - /tmp/custom2.sh persistence.dnsConfig object {} Add custom dns config persistence.dnsPolicy string \"\" Add custom dns policy persistence.image.pullPolicy string \"IfNotPresent\" Image pullPolicy to use for deploying. persistence.image.pullSecrets list [] Image Pull Secrets persistence.image.repository string \"ghcr.io/janssenproject/jans/persistence-loader\" Image to use for deploying. persistence.image.tag string \"1.1.6_dev\" Image tag to use for deploying. persistence.resources object {\"limits\":{\"cpu\":\"300m\",\"memory\":\"300Mi\"},\"requests\":{\"cpu\":\"300m\",\"memory\":\"300Mi\"}} Resource specs. persistence.resources.limits.cpu string \"300m\" CPU limit persistence.resources.limits.memory string \"300Mi\" Memory limit. persistence.resources.requests.cpu string \"300m\" CPU request. persistence.resources.requests.memory string \"300Mi\" Memory request. persistence.usrEnvs object {\"normal\":{},\"secret\":{}} Add custom normal and secret envs to the service persistence.usrEnvs.normal object {} Add custom normal envs to the service variable1: value1 persistence.usrEnvs.secret object {} Add custom secret envs to the service variable1: value1 persistence.volumeMounts list [] Configure any additional volumesMounts that need to be attached to the containers persistence.volumes list [] Configure any additional volumes that need to be attached to the pod saml object {\"additionalAnnotations\":{},\"additionalLabels\":{},\"customScripts\":[],\"dnsConfig\":{},\"dnsPolicy\":\"\",\"hpa\":{\"behavior\":{},\"enabled\":true,\"maxReplicas\":10,\"metrics\":[],\"minReplicas\":1,\"targetCPUUtilizationPercentage\":50},\"image\":{\"pullPolicy\":\"IfNotPresent\",\"pullSecrets\":[],\"repository\":\"ghcr.io/janssenproject/jans/saml\",\"tag\":\"1.1.6_dev\"},\"lifecycle\":{},\"livenessProbe\":{\"exec\":{\"command\":[\"python3\",\"/app/scripts/healthcheck.py\"]},\"failureThreshold\":10,\"initialDelaySeconds\":30,\"periodSeconds\":30,\"timeoutSeconds\":5},\"pdb\":{\"enabled\":true,\"maxUnavailable\":\"90%\"},\"readinessProbe\":{\"exec\":{\"command\":[\"python3\",\"/app/scripts/healthcheck.py\"]},\"failureThreshold\":10,\"initialDelaySeconds\":25,\"periodSeconds\":25,\"timeoutSeconds\":5},\"replicas\":1,\"resources\":{\"limits\":{\"cpu\":\"500m\",\"memory\":\"1200Mi\"},\"requests\":{\"cpu\":\"500m\",\"memory\":\"1200Mi\"}},\"topologySpreadConstraints\":{},\"usrEnvs\":{\"normal\":{},\"secret\":{}},\"volumeMounts\":[],\"volumes\":[]} SAML. saml.additionalAnnotations object {} Additional annotations that will be added across the gateway in the format of saml.additionalLabels object {} Additional labels that will be added across the gateway in the format of saml.customScripts list [] Add custom scripts that have been mounted to run before the entrypoint. - /tmp/custom.sh - /tmp/custom2.sh saml.dnsConfig object {} Add custom dns config saml.dnsPolicy string \"\" Add custom dns policy saml.hpa object {\"behavior\":{},\"enabled\":true,\"maxReplicas\":10,\"metrics\":[],\"minReplicas\":1,\"targetCPUUtilizationPercentage\":50} Configure the HorizontalPodAutoscaler saml.hpa.behavior object {} Scaling Policies saml.hpa.metrics list [] metrics if targetCPUUtilizationPercentage is not set saml.image.pullPolicy string \"IfNotPresent\" Image pullPolicy to use for deploying. saml.image.pullSecrets list [] Image Pull Secrets saml.image.repository string \"ghcr.io/janssenproject/jans/saml\" Image to use for deploying. saml.image.tag string \"1.1.6_dev\" Image tag to use for deploying. saml.livenessProbe object {\"exec\":{\"command\":[\"python3\",\"/app/scripts/healthcheck.py\"]},\"failureThreshold\":10,\"initialDelaySeconds\":30,\"periodSeconds\":30,\"timeoutSeconds\":5} Configure the liveness healthcheck for the auth server if needed. saml.livenessProbe.exec object {\"command\":[\"python3\",\"/app/scripts/healthcheck.py\"]} http liveness probe endpoint saml.pdb object {\"enabled\":true,\"maxUnavailable\":\"90%\"} Configure the PodDisruptionBudget saml.readinessProbe.exec object {\"command\":[\"python3\",\"/app/scripts/healthcheck.py\"]} http readiness probe endpoint saml.replicas int 1 Service replica number. saml.resources object {\"limits\":{\"cpu\":\"500m\",\"memory\":\"1200Mi\"},\"requests\":{\"cpu\":\"500m\",\"memory\":\"1200Mi\"}} Resource specs. saml.resources.limits.cpu string \"500m\" CPU limit. saml.resources.limits.memory string \"1200Mi\" Memory limit. This value is used to calculate memory allocation for Java. Currently it only supports Mi . Please refrain from using other units. saml.resources.requests.cpu string \"500m\" CPU request. saml.resources.requests.memory string \"1200Mi\" Memory request. saml.topologySpreadConstraints object {} Configure the topology spread constraints. Notice this is a map NOT a list as in the upstream API https://kubernetes.io/docs/concepts/scheduling-eviction/topology-spread-constraints/ saml.usrEnvs object {\"normal\":{},\"secret\":{}} Add custom normal and secret envs to the service saml.usrEnvs.normal object {} Add custom normal envs to the service variable1: value1 saml.usrEnvs.secret object {} Add custom secret envs to the service variable1: value1 saml.volumeMounts list [] Configure any additional volumesMounts that need to be attached to the containers saml.volumes list [] Configure any additional volumes that need to be attached to the pod scim object {\"additionalAnnotations\":{},\"additionalLabels\":{},\"customScripts\":[],\"dnsConfig\":{},\"dnsPolicy\":\"\",\"hpa\":{\"behavior\":{},\"enabled\":true,\"maxReplicas\":10,\"metrics\":[],\"minReplicas\":1,\"targetCPUUtilizationPercentage\":50},\"image\":{\"pullPolicy\":\"IfNotPresent\",\"pullSecrets\":[],\"repository\":\"ghcr.io/janssenproject/jans/scim\",\"tag\":\"1.1.6_dev\"},\"lifecycle\":{},\"livenessProbe\":{\"httpGet\":{\"path\":\"/jans-scim/sys/health-check\",\"port\":8080},\"initialDelaySeconds\":30,\"periodSeconds\":30,\"timeoutSeconds\":5},\"pdb\":{\"enabled\":true,\"maxUnavailable\":\"90%\"},\"readinessProbe\":{\"httpGet\":{\"path\":\"/jans-scim/sys/health-check\",\"port\":8080},\"initialDelaySeconds\":25,\"periodSeconds\":25,\"timeoutSeconds\":5},\"replicas\":1,\"resources\":{\"limits\":{\"cpu\":\"1000m\",\"memory\":\"1200Mi\"},\"requests\":{\"cpu\":\"1000m\",\"memory\":\"1200Mi\"}},\"service\":{\"name\":\"http-scim\",\"port\":8080},\"topologySpreadConstraints\":{},\"usrEnvs\":{\"normal\":{},\"secret\":{}},\"volumeMounts\":[],\"volumes\":[]} System for Cross-domain Identity Management (SCIM) version 2.0 scim.additionalAnnotations object {} Additional annotations that will be added across the gateway in the format of scim.additionalLabels object {} Additional labels that will be added across the gateway in the format of scim.customScripts list [] Add custom scripts that have been mounted to run before the entrypoint. - /tmp/custom.sh - /tmp/custom2.sh scim.dnsConfig object {} Add custom dns config scim.dnsPolicy string \"\" Add custom dns policy scim.hpa object {\"behavior\":{},\"enabled\":true,\"maxReplicas\":10,\"metrics\":[],\"minReplicas\":1,\"targetCPUUtilizationPercentage\":50} Configure the HorizontalPodAutoscaler scim.hpa.behavior object {} Scaling Policies scim.hpa.metrics list [] metrics if targetCPUUtilizationPercentage is not set scim.image.pullPolicy string \"IfNotPresent\" Image pullPolicy to use for deploying. scim.image.pullSecrets list [] Image Pull Secrets scim.image.repository string \"ghcr.io/janssenproject/jans/scim\" Image to use for deploying. scim.image.tag string \"1.1.6_dev\" Image tag to use for deploying. scim.livenessProbe object {\"httpGet\":{\"path\":\"/jans-scim/sys/health-check\",\"port\":8080},\"initialDelaySeconds\":30,\"periodSeconds\":30,\"timeoutSeconds\":5} Configure the liveness healthcheck for SCIM if needed. scim.livenessProbe.httpGet.path string \"/jans-scim/sys/health-check\" http liveness probe endpoint scim.pdb object {\"enabled\":true,\"maxUnavailable\":\"90%\"} Configure the PodDisruptionBudget scim.readinessProbe object {\"httpGet\":{\"path\":\"/jans-scim/sys/health-check\",\"port\":8080},\"initialDelaySeconds\":25,\"periodSeconds\":25,\"timeoutSeconds\":5} Configure the readiness healthcheck for the SCIM if needed. scim.readinessProbe.httpGet.path string \"/jans-scim/sys/health-check\" http readiness probe endpoint scim.replicas int 1 Service replica number. scim.resources.limits.cpu string \"1000m\" CPU limit. scim.resources.limits.memory string \"1200Mi\" Memory limit. This value is used to calculate memory allocation for Java. Currently it only supports Mi . Please refrain from using other units. scim.resources.requests.cpu string \"1000m\" CPU request. scim.resources.requests.memory string \"1200Mi\" Memory request. scim.service.name string \"http-scim\" The name of the scim port within the scim service. Please keep it as default. scim.service.port int 8080 Port of the scim service. Please keep it as default. scim.topologySpreadConstraints object {} Configure the topology spread constraints. Notice this is a map NOT a list as in the upstream API https://kubernetes.io/docs/concepts/scheduling-eviction/topology-spread-constraints/ scim.usrEnvs object {\"normal\":{},\"secret\":{}} Add custom normal and secret envs to the service scim.usrEnvs.normal object {} Add custom normal envs to the service variable1: value1 scim.usrEnvs.secret object {} Add custom secret envs to the service variable1: value1 scim.volumeMounts list [] Configure any additional volumesMounts that need to be attached to the containers scim.volumes list [] Configure any additional volumes that need to be attached to the pod Autogenerated from chart metadata using helm-docs v1.13.1","title":"Flex Helm Chart"},{"location":"reference/kubernetes/helm-chart/#gluu","text":"Gluu Access and Identity Management Homepage: https://www.gluu.org","title":"gluu"},{"location":"reference/kubernetes/helm-chart/#maintainers","text":"Name Email Url moabu team@gluu.org","title":"Maintainers"},{"location":"reference/kubernetes/helm-chart/#source-code","text":"https://docs.gluu.org","title":"Source Code"},{"location":"reference/kubernetes/helm-chart/#requirements","text":"Kubernetes: >=v1.21.0-0 Repository Name Version admin-ui 5.1.4 auth-server 1.1.4 auth-server-key-rotation 1.1.4 casa 1.1.4 cn-istio-ingress 5.1.4 config 1.1.4 config-api 1.1.4 fido2 1.1.4 kc-scheduler 1.1.4 link 1.1.4 nginx-ingress 5.1.4 persistence 1.1.4 saml 1.1.4 scim 1.1.4","title":"Requirements"},{"location":"reference/kubernetes/helm-chart/#values","text":"Key Type Default Description admin-ui object {\"additionalAnnotations\":{},\"additionalLabels\":{},\"customScripts\":[],\"dnsConfig\":{},\"dnsPolicy\":\"\",\"hpa\":{\"behavior\":{},\"enabled\":true,\"maxReplicas\":10,\"metrics\":[],\"minReplicas\":1,\"targetCPUUtilizationPercentage\":50},\"image\":{\"pullPolicy\":\"IfNotPresent\",\"pullSecrets\":[],\"repository\":\"ghcr.io/gluufederation/flex/admin-ui\",\"tag\":\"5.1.3-1\"},\"lifecycle\":{},\"livenessProbe\":{\"failureThreshold\":20,\"initialDelaySeconds\":60,\"periodSeconds\":25,\"tcpSocket\":{\"port\":8080},\"timeoutSeconds\":5},\"pdb\":{\"enabled\":true,\"maxUnavailable\":\"90%\"},\"readinessProbe\":{\"failureThreshold\":20,\"initialDelaySeconds\":60,\"periodSeconds\":25,\"tcpSocket\":{\"port\":8080},\"timeoutSeconds\":5},\"replicas\":1,\"resources\":{\"limits\":{\"cpu\":\"2000m\",\"memory\":\"2000Mi\"},\"requests\":{\"cpu\":\"2000m\",\"memory\":\"2000Mi\"}},\"topologySpreadConstraints\":{},\"usrEnvs\":{\"normal\":{},\"secret\":{}},\"volumeMounts\":[],\"volumes\":[]} Admin GUI for configuration of the auth-server admin-ui.additionalAnnotations object {} Additional annotations that will be added across the gateway in the format of admin-ui.additionalLabels object {} Additional labels that will be added across the gateway in the format of admin-ui.customScripts list [] Add custom scripts that have been mounted to run before the entrypoint. - /tmp/custom.sh - /tmp/custom2.sh admin-ui.dnsConfig object {} Add custom dns config admin-ui.dnsPolicy string \"\" Add custom dns policy admin-ui.hpa object {\"behavior\":{},\"enabled\":true,\"maxReplicas\":10,\"metrics\":[],\"minReplicas\":1,\"targetCPUUtilizationPercentage\":50} Configure the HorizontalPodAutoscaler admin-ui.hpa.behavior object {} Scaling Policies admin-ui.hpa.metrics list [] metrics if targetCPUUtilizationPercentage is not set admin-ui.image.pullPolicy string \"IfNotPresent\" Image pullPolicy to use for deploying. admin-ui.image.pullSecrets list [] Image Pull Secrets admin-ui.image.repository string \"ghcr.io/gluufederation/flex/admin-ui\" Image to use for deploying. admin-ui.image.tag string \"5.1.3-1\" Image tag to use for deploying. admin-ui.livenessProbe object {\"failureThreshold\":20,\"initialDelaySeconds\":60,\"periodSeconds\":25,\"tcpSocket\":{\"port\":8080},\"timeoutSeconds\":5} Configure the liveness healthcheck for the admin ui if needed. admin-ui.pdb object {\"enabled\":true,\"maxUnavailable\":\"90%\"} Configure the PodDisruptionBudget admin-ui.readinessProbe object {\"failureThreshold\":20,\"initialDelaySeconds\":60,\"periodSeconds\":25,\"tcpSocket\":{\"port\":8080},\"timeoutSeconds\":5} Configure the readiness healthcheck for the admin ui if needed. admin-ui.replicas int 1 Service replica number. admin-ui.resources object {\"limits\":{\"cpu\":\"2000m\",\"memory\":\"2000Mi\"},\"requests\":{\"cpu\":\"2000m\",\"memory\":\"2000Mi\"}} Resource specs. admin-ui.resources.limits.cpu string \"2000m\" CPU limit. admin-ui.resources.limits.memory string \"2000Mi\" Memory limit. admin-ui.resources.requests.cpu string \"2000m\" CPU request. admin-ui.resources.requests.memory string \"2000Mi\" Memory request. admin-ui.topologySpreadConstraints object {} Configure the topology spread constraints. Notice this is a map NOT a list as in the upstream API https://kubernetes.io/docs/concepts/scheduling-eviction/topology-spread-constraints/ admin-ui.usrEnvs object {\"normal\":{},\"secret\":{}} Add custom normal and secret envs to the service admin-ui.usrEnvs.normal object {} Add custom normal envs to the service variable1: value1 admin-ui.usrEnvs.secret object {} Add custom secret envs to the service variable1: value1 admin-ui.volumeMounts list [] Configure any additional volumesMounts that need to be attached to the containers admin-ui.volumes list [] Configure any additional volumes that need to be attached to the pod auth-server object {\"additionalAnnotations\":{},\"additionalLabels\":{},\"customScripts\":[],\"dnsConfig\":{},\"dnsPolicy\":\"\",\"hpa\":{\"behavior\":{},\"enabled\":true,\"maxReplicas\":10,\"metrics\":[],\"minReplicas\":1,\"targetCPUUtilizationPercentage\":50},\"image\":{\"pullPolicy\":\"IfNotPresent\",\"pullSecrets\":[],\"repository\":\"ghcr.io/janssenproject/jans/auth-server\",\"tag\":\"1.1.6_dev\"},\"lifecycle\":{},\"livenessProbe\":{\"exec\":{\"command\":[\"python3\",\"/app/scripts/healthcheck.py\"]},\"initialDelaySeconds\":30,\"periodSeconds\":30,\"timeoutSeconds\":5},\"pdb\":{\"enabled\":true,\"maxUnavailable\":\"90%\"},\"readinessProbe\":{\"exec\":{\"command\":[\"python3\",\"/app/scripts/healthcheck.py\"]},\"initialDelaySeconds\":25,\"periodSeconds\":25,\"timeoutSeconds\":5},\"replicas\":1,\"resources\":{\"limits\":{\"cpu\":\"2500m\",\"memory\":\"2500Mi\"},\"requests\":{\"cpu\":\"2500m\",\"memory\":\"2500Mi\"}},\"topologySpreadConstraints\":{},\"usrEnvs\":{\"normal\":{},\"secret\":{}},\"volumeMounts\":[],\"volumes\":[]} OAuth Authorization Server, the OpenID Connect Provider, the UMA Authorization Server--this is the main Internet facing component of Gluu. It's the service that returns tokens, JWT's and identity assertions. This service must be Internet facing. auth-server-key-rotation object {\"additionalAnnotations\":{},\"additionalLabels\":{},\"customScripts\":[],\"dnsConfig\":{},\"dnsPolicy\":\"\",\"image\":{\"pullPolicy\":\"IfNotPresent\",\"pullSecrets\":[],\"repository\":\"ghcr.io/janssenproject/jans/certmanager\",\"tag\":\"1.1.6_dev\"},\"keysLife\":48,\"keysPushDelay\":0,\"keysPushStrategy\":\"NEWER\",\"keysStrategy\":\"NEWER\",\"lifecycle\":{},\"resources\":{\"limits\":{\"cpu\":\"300m\",\"memory\":\"300Mi\"},\"requests\":{\"cpu\":\"300m\",\"memory\":\"300Mi\"}},\"usrEnvs\":{\"normal\":{},\"secret\":{}},\"volumeMounts\":[],\"volumes\":[]} Responsible for regenerating auth-keys per x hours auth-server-key-rotation.additionalAnnotations object {} Additional annotations that will be added across the gateway in the format of auth-server-key-rotation.additionalLabels object {} Additional labels that will be added across the gateway in the format of auth-server-key-rotation.customScripts list [] Add custom scripts that have been mounted to run before the entrypoint. - /tmp/custom.sh - /tmp/custom2.sh auth-server-key-rotation.dnsConfig object {} Add custom dns config auth-server-key-rotation.dnsPolicy string \"\" Add custom dns policy auth-server-key-rotation.image.pullPolicy string \"IfNotPresent\" Image pullPolicy to use for deploying. auth-server-key-rotation.image.pullSecrets list [] Image Pull Secrets auth-server-key-rotation.image.repository string \"ghcr.io/janssenproject/jans/certmanager\" Image to use for deploying. auth-server-key-rotation.image.tag string \"1.1.3-1\" Image tag to use for deploying. auth-server-key-rotation.keysLife int 48 Auth server key rotation keys life in hours auth-server-key-rotation.keysPushDelay int 0 Delay (in seconds) before pushing private keys to Auth server auth-server-key-rotation.keysPushStrategy string \"NEWER\" Set key selection strategy after pushing private keys to Auth server (only takes effect when keysPushDelay value is greater than 0) auth-server-key-rotation.keysStrategy string \"NEWER\" Set key selection strategy used by Auth server auth-server-key-rotation.resources object {\"limits\":{\"cpu\":\"300m\",\"memory\":\"300Mi\"},\"requests\":{\"cpu\":\"300m\",\"memory\":\"300Mi\"}} Resource specs. auth-server-key-rotation.resources.limits.cpu string \"300m\" CPU limit. auth-server-key-rotation.resources.limits.memory string \"300Mi\" Memory limit. auth-server-key-rotation.resources.requests.cpu string \"300m\" CPU request. auth-server-key-rotation.resources.requests.memory string \"300Mi\" Memory request. auth-server-key-rotation.usrEnvs object {\"normal\":{},\"secret\":{}} Add custom normal and secret envs to the service auth-server-key-rotation.usrEnvs.normal object {} Add custom normal envs to the service variable1: value1 auth-server-key-rotation.usrEnvs.secret object {} Add custom secret envs to the service variable1: value1 auth-server-key-rotation.volumeMounts list [] Configure any additional volumesMounts that need to be attached to the containers auth-server-key-rotation.volumes list [] Configure any additional volumes that need to be attached to the pod auth-server.additionalAnnotations object {} Additional annotations that will be added across the gateway in the format of auth-server.additionalLabels object {} Additional labels that will be added across the gateway in the format of auth-server.customScripts list [] Add custom scripts that have been mounted to run before the entrypoint. - /tmp/custom.sh - /tmp/custom2.sh auth-server.dnsConfig object {} Add custom dns config auth-server.dnsPolicy string \"\" Add custom dns policy auth-server.hpa object {\"behavior\":{},\"enabled\":true,\"maxReplicas\":10,\"metrics\":[],\"minReplicas\":1,\"targetCPUUtilizationPercentage\":50} Configure the HorizontalPodAutoscaler auth-server.hpa.behavior object {} Scaling Policies auth-server.hpa.metrics list [] metrics if targetCPUUtilizationPercentage is not set auth-server.image.pullPolicy string \"IfNotPresent\" Image pullPolicy to use for deploying. auth-server.image.pullSecrets list [] Image Pull Secrets auth-server.image.repository string \"ghcr.io/janssenproject/jans/auth-server\" Image to use for deploying. auth-server.image.tag string \"1.1.6_dev\" Image tag to use for deploying. auth-server.livenessProbe object {\"exec\":{\"command\":[\"python3\",\"/app/scripts/healthcheck.py\"]},\"initialDelaySeconds\":30,\"periodSeconds\":30,\"timeoutSeconds\":5} Configure the liveness healthcheck for the auth server if needed. auth-server.livenessProbe.exec object {\"command\":[\"python3\",\"/app/scripts/healthcheck.py\"]} Executes the python3 healthcheck. https://github.com/JanssenProject/docker-jans-auth-server/blob/master/scripts/healthcheck.py auth-server.pdb object {\"enabled\":true,\"maxUnavailable\":\"90%\"} Configure the PodDisruptionBudget auth-server.readinessProbe object {\"exec\":{\"command\":[\"python3\",\"/app/scripts/healthcheck.py\"]},\"initialDelaySeconds\":25,\"periodSeconds\":25,\"timeoutSeconds\":5} Configure the readiness healthcheck for the auth server if needed. https://github.com/JanssenProject/docker-jans-auth-server/blob/master/scripts/healthcheck.py auth-server.replicas int 1 Service replica number. auth-server.resources object {\"limits\":{\"cpu\":\"2500m\",\"memory\":\"2500Mi\"},\"requests\":{\"cpu\":\"2500m\",\"memory\":\"2500Mi\"}} Resource specs. auth-server.resources.limits.cpu string \"2500m\" CPU limit. auth-server.resources.limits.memory string \"2500Mi\" Memory limit. This value is used to calculate memory allocation for Java. Currently it only supports Mi . Please refrain from using other units. auth-server.resources.requests.cpu string \"2500m\" CPU request. auth-server.resources.requests.memory string \"2500Mi\" Memory request. auth-server.topologySpreadConstraints object {} Configure the topology spread constraints. Notice this is a map NOT a list as in the upstream API https://kubernetes.io/docs/concepts/scheduling-eviction/topology-spread-constraints/ auth-server.usrEnvs object {\"normal\":{},\"secret\":{}} Add custom normal and secret envs to the service auth-server.usrEnvs.normal object {} Add custom normal envs to the service variable1: value1 auth-server.usrEnvs.secret object {} Add custom secret envs to the service variable1: value1 auth-server.volumeMounts list [] Configure any additional volumesMounts that need to be attached to the containers auth-server.volumes list [] Configure any additional volumes that need to be attached to the pod casa object {\"additionalAnnotations\":{},\"additionalLabels\":{},\"customScripts\":[],\"dnsConfig\":{},\"dnsPolicy\":\"\",\"hpa\":{\"behavior\":{},\"enabled\":true,\"maxReplicas\":10,\"metrics\":[],\"minReplicas\":1,\"targetCPUUtilizationPercentage\":50},\"image\":{\"pullPolicy\":\"IfNotPresent\",\"pullSecrets\":[],\"repository\":\"ghcr.io/janssenproject/jans/casa\",\"tag\":\"1.1.6_dev\"},\"lifecycle\":{},\"livenessProbe\":{\"httpGet\":{\"path\":\"/jans-casa/health-check\",\"port\":\"http-casa\"},\"initialDelaySeconds\":25,\"periodSeconds\":25,\"timeoutSeconds\":5},\"pdb\":{\"enabled\":true,\"maxUnavailable\":\"90%\"},\"readinessProbe\":{\"httpGet\":{\"path\":\"/jans-casa/health-check\",\"port\":\"http-casa\"},\"initialDelaySeconds\":30,\"periodSeconds\":30,\"timeoutSeconds\":5},\"replicas\":1,\"resources\":{\"limits\":{\"cpu\":\"500m\",\"memory\":\"500Mi\"},\"requests\":{\"cpu\":\"500m\",\"memory\":\"500Mi\"}},\"topologySpreadConstraints\":{},\"usrEnvs\":{\"normal\":{},\"secret\":{}},\"volumeMounts\":[],\"volumes\":[]} Janssen Casa (\"Casa\") is a self-service web portal for end-users to manage authentication and authorization preferences for their account in a Janssen Auth Server. casa.additionalAnnotations object {} Additional annotations that will be added across the gateway in the format of casa.additionalLabels object {} Additional labels that will be added across the gateway in the format of casa.customScripts list [] Add custom scripts that have been mounted to run before the entrypoint. - /tmp/custom.sh - /tmp/custom2.sh casa.dnsConfig object {} Add custom dns config casa.dnsPolicy string \"\" Add custom dns policy casa.hpa object {\"behavior\":{},\"enabled\":true,\"maxReplicas\":10,\"metrics\":[],\"minReplicas\":1,\"targetCPUUtilizationPercentage\":50} Configure the HorizontalPodAutoscaler casa.hpa.behavior object {} Scaling Policies casa.hpa.metrics list [] metrics if targetCPUUtilizationPercentage is not set casa.image.pullPolicy string \"IfNotPresent\" Image pullPolicy to use for deploying. casa.image.pullSecrets list [] Image Pull Secrets casa.image.repository string \"ghcr.io/janssenproject/jans/casa\" Image to use for deploying. casa.image.tag string \"1.1.6_dev\" Image tag to use for deploying. casa.livenessProbe object {\"httpGet\":{\"path\":\"/jans-casa/health-check\",\"port\":\"http-casa\"},\"initialDelaySeconds\":25,\"periodSeconds\":25,\"timeoutSeconds\":5} Configure the liveness healthcheck for casa if needed. casa.livenessProbe.httpGet.path string \"/jans-casa/health-check\" http liveness probe endpoint casa.pdb object {\"enabled\":true,\"maxUnavailable\":\"90%\"} Configure the PodDisruptionBudget casa.readinessProbe object {\"httpGet\":{\"path\":\"/jans-casa/health-check\",\"port\":\"http-casa\"},\"initialDelaySeconds\":30,\"periodSeconds\":30,\"timeoutSeconds\":5} Configure the readiness healthcheck for the casa if needed. casa.readinessProbe.httpGet.path string \"/jans-casa/health-check\" http readiness probe endpoint casa.replicas int 1 Service replica number. casa.resources object {\"limits\":{\"cpu\":\"500m\",\"memory\":\"500Mi\"},\"requests\":{\"cpu\":\"500m\",\"memory\":\"500Mi\"}} Resource specs. casa.resources.limits.cpu string \"500m\" CPU limit. casa.resources.limits.memory string \"500Mi\" Memory limit. This value is used to calculate memory allocation for Java. Currently it only supports Mi . Please refrain from using other units. casa.resources.requests.cpu string \"500m\" CPU request. casa.resources.requests.memory string \"500Mi\" Memory request. casa.topologySpreadConstraints object {} Configure the topology spread constraints. Notice this is a map NOT a list as in the upstream API https://kubernetes.io/docs/concepts/scheduling-eviction/topology-spread-constraints/ casa.usrEnvs object {\"normal\":{},\"secret\":{}} Add custom normal and secret envs to the service casa.usrEnvs.normal object {} Add custom normal envs to the service variable1: value1 casa.usrEnvs.secret object {} Add custom secret envs to the service variable1: value1 casa.volumeMounts list [] Configure any additional volumesMounts that need to be attached to the containers casa.volumes list [] Configure any additional volumes that need to be attached to the pod config object {\"additionalAnnotations\":{},\"additionalLabels\":{},\"adminPassword\":\"Test1234#\",\"city\":\"Austin\",\"configmap\":{\"cnAwsAccessKeyId\":\"\",\"cnAwsDefaultRegion\":\"us-west-1\",\"cnAwsProfile\":\"gluu\",\"cnAwsSecretAccessKey\":\"\",\"cnAwsSecretsEndpointUrl\":\"\",\"cnAwsSecretsNamePrefix\":\"gluu\",\"cnAwsSecretsReplicaRegions\":[],\"cnCacheType\":\"NATIVE_PERSISTENCE\",\"cnConfigKubernetesConfigMap\":\"cn\",\"cnCouchbaseBucketPrefix\":\"jans\",\"cnCouchbaseCrt\":\"SWFtTm90YVNlcnZpY2VBY2NvdW50Q2hhbmdlTWV0b09uZQo=\",\"cnCouchbaseIndexNumReplica\":0,\"cnCouchbasePassword\":\"P@ssw0rd\",\"cnCouchbaseSuperUser\":\"admin\",\"cnCouchbaseSuperUserPassword\":\"Test1234#\",\"cnCouchbaseUrl\":\"cbgluu.default.svc.cluster.local\",\"cnCouchbaseUser\":\"gluu\",\"cnGoogleProjectId\":\"google-project-to-save-config-and-secrets-to\",\"cnGoogleSecretManagerServiceAccount\":\"SWFtTm90YVNlcnZpY2VBY2NvdW50Q2hhbmdlTWV0b09uZQo=\",\"cnGoogleSecretNamePrefix\":\"gluu\",\"cnGoogleSecretVersionId\":\"latest\",\"cnGoogleSpannerDatabaseId\":\"\",\"cnGoogleSpannerInstanceId\":\"\",\"cnJettyRequestHeaderSize\":8192,\"cnLdapCrt\":\"SWFtTm90YVNlcnZpY2VBY2NvdW50Q2hhbmdlTWV0b09uZQo=\",\"cnLdapKey\":\"SWFtTm90YVNlcnZpY2VBY2NvdW50Q2hhbmdlTWV0b09uZQo=\",\"cnLdapUrl\":\"opendj:1636\",\"cnMaxRamPercent\":\"75.0\",\"cnMessageType\":\"DISABLED\",\"cnOpaUrl\":\"http://opa.opa.svc.cluster.cluster.local:8181/v1\",\"cnPersistenceHybridMapping\":\"{}\",\"cnRedisSentinelGroup\":\"\",\"cnRedisSslTruststore\":\"\",\"cnRedisType\":\"STANDALONE\",\"cnRedisUrl\":\"redis.redis.svc.cluster.local:6379\",\"cnRedisUseSsl\":false,\"cnScimProtectionMode\":\"OAUTH\",\"cnSecretKubernetesSecret\":\"cn\",\"cnSqlDbDialect\":\"mysql\",\"cnSqlDbHost\":\"my-release-mysql.default.svc.cluster.local\",\"cnSqlDbName\":\"gluu\",\"cnSqlDbPort\":3306,\"cnSqlDbSchema\":\"\",\"cnSqlDbTimezone\":\"UTC\",\"cnSqlDbUser\":\"gluu\",\"cnSqldbUserPassword\":\"Test1234#\",\"cnVaultAddr\":\"http://localhost:8200\",\"cnVaultAppRolePath\":\"approle\",\"cnVaultKvPath\":\"secret\",\"cnVaultNamespace\":\"\",\"cnVaultPrefix\":\"jans\",\"cnVaultRoleId\":\"\",\"cnVaultRoleIdFile\":\"/etc/certs/vault_role_id\",\"cnVaultSecretId\":\"\",\"cnVaultSecretIdFile\":\"/etc/certs/vault_secret_id\",\"cnVaultVerify\":false,\"kcDbPassword\":\"Test1234#\",\"kcDbSchema\":\"keycloak\",\"kcDbUrlDatabase\":\"keycloak\",\"kcDbUrlHost\":\"mysql.kc.svc.cluster.local\",\"kcDbUrlPort\":3306,\"kcDbUrlProperties\":\"?useUnicode=true&characterEncoding=UTF-8&character_set_server=utf8mb4\",\"kcDbUsername\":\"keycloak\",\"kcDbVendor\":\"mysql\",\"kcLogLevel\":\"INFO\",\"lbAddr\":\"\",\"quarkusTransactionEnableRecovery\":true},\"countryCode\":\"US\",\"customScripts\":[],\"dnsConfig\":{},\"dnsPolicy\":\"\",\"email\":\"team@gluu.org\",\"image\":{\"pullSecrets\":[],\"repository\":\"ghcr.io/janssenproject/jans/configurator\",\"tag\":\"1.1.6_dev\"},\"ldapPassword\":\"P@ssw0rds\",\"ldapTruststorePassword\":\"changeit\",\"lifecycle\":{},\"migration\":{\"enabled\":false,\"migrationDataFormat\":\"ldif\",\"migrationDir\":\"/ce-migration\"},\"orgName\":\"Gluu\",\"redisPassword\":\"P@assw0rd\",\"resources\":{\"limits\":{\"cpu\":\"300m\",\"memory\":\"300Mi\"},\"requests\":{\"cpu\":\"300m\",\"memory\":\"300Mi\"}},\"salt\":\"\",\"state\":\"TX\",\"usrEnvs\":{\"normal\":{},\"secret\":{}},\"volumeMounts\":[],\"volumes\":[]} Configuration parameters for setup and initial configuration secret and config layers used by Gluu services. config-api object {\"additionalAnnotations\":{},\"additionalLabels\":{},\"customScripts\":[],\"dnsConfig\":{},\"dnsPolicy\":\"\",\"hpa\":{\"behavior\":{},\"enabled\":true,\"maxReplicas\":10,\"metrics\":[],\"minReplicas\":1,\"targetCPUUtilizationPercentage\":50},\"image\":{\"pullPolicy\":\"IfNotPresent\",\"pullSecrets\":[],\"repository\":\"ghcr.io/janssenproject/jans/config-api\",\"tag\":\"1.1.6_dev\"},\"lifecycle\":{},\"livenessProbe\":{\"httpGet\":{\"path\":\"/jans-config-api/api/v1/health/live\",\"port\":8074},\"initialDelaySeconds\":30,\"periodSeconds\":30,\"timeoutSeconds\":5},\"pdb\":{\"enabled\":true,\"maxUnavailable\":\"90%\"},\"readinessProbe\":{\"httpGet\":{\"path\":\"jans-config-api/api/v1/health/ready\",\"port\":8074},\"initialDelaySeconds\":25,\"periodSeconds\":25,\"timeoutSeconds\":5},\"replicas\":1,\"resources\":{\"limits\":{\"cpu\":\"1000m\",\"memory\":\"1200Mi\"},\"requests\":{\"cpu\":\"1000m\",\"memory\":\"1200Mi\"}},\"topologySpreadConstraints\":{},\"usrEnvs\":{\"normal\":{},\"secret\":{}},\"volumeMounts\":[],\"volumes\":[]} Config Api endpoints can be used to configure the auth-server, which is an open-source OpenID Connect Provider (OP) and UMA Authorization Server (AS). config-api.additionalAnnotations object {} Additional annotations that will be added across the gateway in the format of config-api.additionalLabels object {} Additional labels that will be added across the gateway in the format of config-api.customScripts list [] Add custom scripts that have been mounted to run before the entrypoint. - /tmp/custom.sh - /tmp/custom2.sh config-api.dnsConfig object {} Add custom dns config config-api.dnsPolicy string \"\" Add custom dns policy config-api.hpa object {\"behavior\":{},\"enabled\":true,\"maxReplicas\":10,\"metrics\":[],\"minReplicas\":1,\"targetCPUUtilizationPercentage\":50} Configure the HorizontalPodAutoscaler config-api.hpa.behavior object {} Scaling Policies config-api.hpa.metrics list [] metrics if targetCPUUtilizationPercentage is not set config-api.image.pullPolicy string \"IfNotPresent\" Image pullPolicy to use for deploying. config-api.image.pullSecrets list [] Image Pull Secrets config-api.image.repository string \"ghcr.io/janssenproject/jans/config-api\" Image to use for deploying. config-api.image.tag string \"1.1.6_dev\" Image tag to use for deploying. config-api.livenessProbe object {\"httpGet\":{\"path\":\"/jans-config-api/api/v1/health/live\",\"port\":8074},\"initialDelaySeconds\":30,\"periodSeconds\":30,\"timeoutSeconds\":5} Configure the liveness healthcheck for the auth server if needed. config-api.livenessProbe.httpGet object {\"path\":\"/jans-config-api/api/v1/health/live\",\"port\":8074} http liveness probe endpoint config-api.pdb object {\"enabled\":true,\"maxUnavailable\":\"90%\"} Configure the PodDisruptionBudget config-api.readinessProbe.httpGet object {\"path\":\"jans-config-api/api/v1/health/ready\",\"port\":8074} http readiness probe endpoint config-api.replicas int 1 Service replica number. config-api.resources object {\"limits\":{\"cpu\":\"1000m\",\"memory\":\"1200Mi\"},\"requests\":{\"cpu\":\"1000m\",\"memory\":\"1200Mi\"}} Resource specs. config-api.resources.limits.cpu string \"1000m\" CPU limit. config-api.resources.limits.memory string \"1200Mi\" Memory limit. This value is used to calculate memory allocation for Java. Currently it only supports Mi . Please refrain from using other units. config-api.resources.requests.cpu string \"1000m\" CPU request. config-api.resources.requests.memory string \"1200Mi\" Memory request. config-api.topologySpreadConstraints object {} Configure the topology spread constraints. Notice this is a map NOT a list as in the upstream API https://kubernetes.io/docs/concepts/scheduling-eviction/topology-spread-constraints/ config-api.usrEnvs object {\"normal\":{},\"secret\":{}} Add custom normal and secret envs to the service config-api.usrEnvs.normal object {} Add custom normal envs to the service variable1: value1 config-api.usrEnvs.secret object {} Add custom secret envs to the service variable1: value1 config-api.volumeMounts list [] Configure any additional volumesMounts that need to be attached to the containers config-api.volumes list [] Configure any additional volumes that need to be attached to the pod config.additionalAnnotations object {} Additional annotations that will be added across the gateway in the format of config.additionalLabels object {} Additional labels that will be added across the gateway in the format of config.adminPassword string \"Test1234#\" Admin password to log in to the UI. config.city string \"Austin\" City. Used for certificate creation. config.configmap.cnCacheType string \"NATIVE_PERSISTENCE\" Cache type. NATIVE_PERSISTENCE , REDIS . or IN_MEMORY . Defaults to NATIVE_PERSISTENCE . config.configmap.cnConfigKubernetesConfigMap string \"cn\" The name of the Kubernetes ConfigMap that will hold the configuration layer config.configmap.cnCouchbaseBucketPrefix string \"jans\" The prefix of couchbase buckets. This helps with separation in between different environments and allows for the same couchbase cluster to be used by different setups of Gluu. config.configmap.cnCouchbaseCrt string \"SWFtTm90YVNlcnZpY2VBY2NvdW50Q2hhbmdlTWV0b09uZQo=\" Couchbase certificate authority string. This must be encoded using base64. This can also be found in your couchbase UI Security > Root Certificate. In mTLS setups this is not required. config.configmap.cnCouchbaseIndexNumReplica int 0 The number of replicas per index created. Please note that the number of index nodes must be one greater than the number of index replicas. That means if your couchbase cluster only has 2 index nodes you cannot place the number of replicas to be higher than 1. config.configmap.cnCouchbasePassword string \"P@ssw0rd\" Couchbase password for the restricted user config.configmap.cnCouchbaseUser that is often used inside the services. The password must contain one digit, one uppercase letter, one lower case letter and one symbol . config.configmap.cnCouchbaseSuperUser string \"admin\" The Couchbase super user (admin) username. This user is used during initialization only. config.configmap.cnCouchbaseSuperUserPassword string \"Test1234#\" Couchbase password for the superuser config.configmap.cnCouchbaseSuperUser that is used during the initialization process. The password must contain one digit, one uppercase letter, one lower case letter and one symbol config.configmap.cnCouchbaseUrl string \"cbgluu.default.svc.cluster.local\" Couchbase URL. Used only when global.cnPersistenceType is hybrid or couchbase. This should be in FQDN format for either remote or local Couchbase clusters. The address can be an internal address inside the kubernetes cluster config.configmap.cnCouchbaseUser string \"gluu\" Couchbase restricted user. Used only when global.cnPersistenceType is hybrid or couchbase. config.configmap.cnGoogleProjectId string \"google-project-to-save-config-and-secrets-to\" Project id of the Google project the secret manager belongs to. Used only when global.configAdapterName and global.configSecretAdapter is set to google. config.configmap.cnGoogleSecretManagerServiceAccount string \"SWFtTm90YVNlcnZpY2VBY2NvdW50Q2hhbmdlTWV0b09uZQo=\" Service account with roles roles/secretmanager.admin base64 encoded string. This is used often inside the services to reach the configuration layer. Used only when global.configAdapterName and global.configSecretAdapter is set to google. config.configmap.cnGoogleSecretNamePrefix string \"gluu\" Prefix for Gluu secret in Google Secret Manager. Defaults to gluu. If left gluu-secret secret will be created. Used only when global.configAdapterName and global.configSecretAdapter is set to google. config.configmap.cnGoogleSecretVersionId string \"latest\" Secret version to be used for secret configuration. Defaults to latest and should normally always stay that way. Used only when global.configAdapterName and global.configSecretAdapter is set to google. config.configmap.cnGoogleSpannerDatabaseId string \"\" Google Spanner Database ID. Used only when global.cnPersistenceType is spanner. config.configmap.cnGoogleSpannerInstanceId string \"\" Google Spanner ID. Used only when global.cnPersistenceType is spanner. config.configmap.cnJettyRequestHeaderSize int 8192 Jetty header size in bytes in the auth server config.configmap.cnLdapCrt string \"SWFtTm90YVNlcnZpY2VBY2NvdW50Q2hhbmdlTWV0b09uZQo=\" OpenDJ certificate string. This must be encoded using base64. config.configmap.cnLdapKey string \"SWFtTm90YVNlcnZpY2VBY2NvdW50Q2hhbmdlTWV0b09uZQo=\" OpenDJ key string. This must be encoded using base64. config.configmap.cnLdapUrl string \"opendj:1636\" OpenDJ internal address. Leave as default. Used when global.cnPersistenceType is set to ldap . config.configmap.cnMaxRamPercent string \"75.0\" Value passed to Java option -XX:MaxRAMPercentage config.configmap.cnMessageType string \"DISABLED\" Message type (one of POSTGRES, REDIS, or DISABLED) config.configmap.cnOpaUrl string \"http://opa.opa.svc.cluster.cluster.local:8181/v1\" URL of OPA API config.configmap.cnPersistenceHybridMapping string \"{}\" Specify data that should be saved in LDAP (one of default, user, cache, site, token, or session; default to default). Note this environment only takes effect when global.cnPersistenceType is set to hybrid . { \"default\": \" 2022-12-20 17:49:55,744 INFO global.auth-server.appLoggers.httpLogLevel string \"INFO\" http_request_response.log level global.auth-server.appLoggers.httpLogTarget string \"FILE\" http_request_response.log target global.auth-server.appLoggers.ldapStatsLogLevel string \"INFO\" jans-auth_persistence_ldap_statistics.log level global.auth-server.appLoggers.ldapStatsLogTarget string \"FILE\" jans-auth_persistence_ldap_statistics.log target global.auth-server.appLoggers.persistenceDurationLogLevel string \"INFO\" jans-auth_persistence_duration.log level global.auth-server.appLoggers.persistenceDurationLogTarget string \"FILE\" jans-auth_persistence_duration.log target global.auth-server.appLoggers.persistenceLogLevel string \"INFO\" jans-auth_persistence.log level global.auth-server.appLoggers.persistenceLogTarget string \"FILE\" jans-auth_persistence.log target global.auth-server.appLoggers.scriptLogLevel string \"INFO\" jans-auth_script.log level global.auth-server.appLoggers.scriptLogTarget string \"FILE\" jans-auth_script.log target global.auth-server.authEncKeys string \"RSA1_5 RSA-OAEP\" space-separated key algorithm for encryption (default to RSA1_5 RSA-OAEP ) global.auth-server.authServerServiceName string \"auth-server\" Name of the auth-server service. Please keep it as default. global.auth-server.authSigKeys string \"RS256 RS384 RS512 ES256 ES384 ES512 PS256 PS384 PS512\" space-separated key algorithm for signing (default to RS256 RS384 RS512 ES256 ES384 ES512 PS256 PS384 PS512 ) global.auth-server.cnCustomJavaOptions string \"\" passing custom java options to auth-server. Notice you do not need to pass in any loggers options as they are introduced below in appLoggers. DO NOT PASS JAVA_OPTIONS in envs. global.auth-server.enabled bool true Boolean flag to enable/disable auth-server chart. You should never set this to false. global.auth-server.ingress object {\"authServerEnabled\":true,\"authServerProtectedRegister\":false,\"authServerProtectedToken\":false,\"deviceCodeEnabled\":true,\"firebaseMessagingEnabled\":true,\"openidConfigEnabled\":true,\"u2fConfigEnabled\":true,\"uma2ConfigEnabled\":true,\"webdiscoveryEnabled\":true,\"webfingerEnabled\":true} Enable endpoints in either istio or nginx ingress depending on users choice global.auth-server.ingress.authServerEnabled bool true Enable Auth server endpoints /jans-auth global.auth-server.ingress.authServerProtectedRegister bool false Enable mTLS onn Auth server endpoint /jans-auth/restv1/register. Currently not working in Istio. global.auth-server.ingress.authServerProtectedToken bool false Enable mTLS on Auth server endpoint /jans-auth/restv1/token. Currently not working in Istio. global.auth-server.ingress.deviceCodeEnabled bool true Enable endpoint /device-code global.auth-server.ingress.firebaseMessagingEnabled bool true Enable endpoint /firebase-messaging-sw.js global.auth-server.ingress.openidConfigEnabled bool true Enable endpoint /.well-known/openid-configuration global.auth-server.ingress.u2fConfigEnabled bool true Enable endpoint /.well-known/fido-configuration global.auth-server.ingress.uma2ConfigEnabled bool true Enable endpoint /.well-known/uma2-configuration global.auth-server.ingress.webdiscoveryEnabled bool true Enable endpoint /.well-known/simple-web-discovery global.auth-server.ingress.webfingerEnabled bool true Enable endpoint /.well-known/webfinger global.auth-server.lockEnabled bool false Enable jans-lock as service running inside auth-server global.awsStorageType string \"io1\" Volume storage type if using AWS volumes. global.azureStorageAccountType string \"Standard_LRS\" Volume storage type if using Azure disks. global.azureStorageKind string \"Managed\" Azure storage kind if using Azure disks global.casa.appLoggers object {\"casaLogLevel\":\"INFO\",\"casaLogTarget\":\"STDOUT\",\"enableStdoutLogPrefix\":\"true\",\"timerLogLevel\":\"INFO\",\"timerLogTarget\":\"FILE\"} App loggers can be configured to define where the logs will be redirected to and the level of each in which it should be displayed. global.casa.appLoggers.casaLogLevel string \"INFO\" casa.log level global.casa.appLoggers.casaLogTarget string \"STDOUT\" casa.log target global.casa.appLoggers.enableStdoutLogPrefix string \"true\" Enable log prefixing which enables prepending the STDOUT logs with the file name. i.e casa ===> 2022-12-20 17:49:55,744 INFO global.casa.appLoggers.timerLogLevel string \"INFO\" casa timer log level global.casa.appLoggers.timerLogTarget string \"FILE\" casa timer log target global.casa.casaServiceName string \"casa\" Name of the casa service. Please keep it as default. global.casa.cnCustomJavaOptions string \"\" passing custom java options to casa. Notice you do not need to pass in any loggers options as they are introduced below in appLoggers. DO NOT PASS JAVA_OPTIONS in envs. global.casa.enabled bool true Boolean flag to enable/disable the casa chart. global.casa.ingress object {\"casaEnabled\":false} Enable endpoints in either istio or nginx ingress depending on users choice global.casa.ingress.casaEnabled bool false Enable casa endpoints /casa global.cloud.testEnviroment bool false Boolean flag if enabled will strip resources requests and limits from all services. global.cnCouchbasePasswordFile string \"/etc/jans/conf/couchbase_password\" Path to Couchbase password file global.cnCouchbaseSuperuserPasswordFile string \"/etc/jans/conf/couchbase_superuser_password\" Path to Couchbase superuser password file global.cnDocumentStoreType string \"DB\" Document store type to use for shibboleth files DB. global.cnGoogleApplicationCredentials string \"/etc/jans/conf/google-credentials.json\" Base64 encoded service account. The sa must have roles/secretmanager.admin to use Google secrets and roles/spanner.databaseUser to use Spanner. Leave as this is a sensible default. global.cnLdapCacertFile string \"/etc/certs/opendj.pem\" Path to OpenDJ CA cert file global.cnLdapCertFile string \"/etc/certs/opendj.crt\" Path to OpenDJ cert file global.cnLdapKeyFile string \"/etc/certs/opendj.key\" Path to OpenDJ key file global.cnLdapPasswordFile string \"/etc/jans/conf/ldap_password\" Path to LDAP password file global.cnLdapTruststoreFile string \"/etc/certs/opendj.pkcs12\" Path to OpenDJ truststore file global.cnLdapTruststorePasswordFile string \"/etc/jans/conf/ldap_truststore_password\" Path to LDAP truststore password file global.cnObExtSigningAlias string \"\" Open banking external signing AS Alias. This is a kid value.Used in SSA Validation, kid used while encoding a JWT sent to token URL i.e. XkwIzWy44xWSlcWnMiEc8iq9s2G global.cnObExtSigningJwksCrt string \"\" Open banking external signing jwks AS certificate authority string. Used in SSA Validation. This must be encoded using base64.. Used when .global.cnObExtSigningJwksUri is set. global.cnObExtSigningJwksKey string \"\" Open banking external signing jwks AS key string. Used in SSA Validation. This must be encoded using base64. Used when .global.cnObExtSigningJwksUri is set. global.cnObExtSigningJwksKeyPassPhrase string \"\" Open banking external signing jwks AS key passphrase to unlock provided key. This must be encoded using base64. Used when .global.cnObExtSigningJwksUri is set. global.cnObExtSigningJwksUri string \"\" Open banking external signing jwks uri. Used in SSA Validation. global.cnObStaticSigningKeyKid string \"\" Open banking signing AS kid to force the AS to use a specific signing key. i.e. Wy44xWSlcWnMiEc8iq9s2G global.cnObTransportAlias string \"\" Open banking transport Alias used inside the JVM. global.cnObTransportCrt string \"\" Open banking AS transport crt. Used in SSA Validation. This must be encoded using base64. global.cnObTransportKey string \"\" Open banking AS transport key. Used in SSA Validation. This must be encoded using base64. global.cnObTransportKeyPassPhrase string \"\" Open banking AS transport key passphrase to unlock AS transport key. This must be encoded using base64. global.cnObTransportTrustStore string \"\" Open banking AS transport truststore crt. This is normally generated from the OB issuing CA, OB Root CA and Signing CA. Used when .global.cnObExtSigningJwksUri is set. Used in SSA Validation. This must be encoded using base64. global.cnPersistenceType string \"sql\" Persistence backend to run Gluu with ldap global.cnPrometheusPort string \"\" Port used by Prometheus JMX agent (default to empty string). To enable Prometheus JMX agent, set the value to a number. global.cnSqlPasswordFile string \"/etc/jans/conf/sql_password\" Path to SQL password file global.config-api.adminUiAppLoggers.adminUiAuditLogLevel string \"INFO\" config-api admin-ui plugin audit log level global.config-api.adminUiAppLoggers.adminUiAuditLogTarget string \"FILE\" config-api admin-ui plugin audit log target global.config-api.adminUiAppLoggers.adminUiLogLevel string \"INFO\" config-api admin-ui plugin log target global.config-api.adminUiAppLoggers.adminUiLogTarget string \"FILE\" config-api admin-ui plugin log level global.config-api.adminUiAppLoggers.enableStdoutLogPrefix string \"true\" Enable log prefixing which enables prepending the STDOUT logs with the file name. i.e config-api_persistence ===> 2022-12-20 17:49:55,744 INFO global.config-api.appLoggers object {\"configApiLogLevel\":\"INFO\",\"configApiLogTarget\":\"STDOUT\",\"enableStdoutLogPrefix\":\"true\",\"ldapStatsLogLevel\":\"INFO\",\"ldapStatsLogTarget\":\"FILE\",\"persistenceDurationLogLevel\":\"INFO\",\"persistenceDurationLogTarget\":\"FILE\",\"persistenceLogLevel\":\"INFO\",\"persistenceLogTarget\":\"FILE\",\"scriptLogLevel\":\"INFO\",\"scriptLogTarget\":\"FILE\"} App loggers can be configured to define where the logs will be redirected to and the level of each in which it should be displayed. global.config-api.appLoggers.configApiLogLevel string \"INFO\" configapi.log level global.config-api.appLoggers.configApiLogTarget string \"STDOUT\" configapi.log target global.config-api.appLoggers.enableStdoutLogPrefix string \"true\" Enable log prefixing which enables prepending the STDOUT logs with the file name. i.e config-api_persistence ===> 2022-12-20 17:49:55,744 INFO global.config-api.appLoggers.ldapStatsLogLevel string \"INFO\" config-api_persistence_ldap_statistics.log level global.config-api.appLoggers.ldapStatsLogTarget string \"FILE\" config-api_persistence_ldap_statistics.log target global.config-api.appLoggers.persistenceDurationLogLevel string \"INFO\" config-api_persistence_duration.log level global.config-api.appLoggers.persistenceDurationLogTarget string \"FILE\" config-api_persistence_duration.log target global.config-api.appLoggers.persistenceLogLevel string \"INFO\" config-api_persistence.log level global.config-api.appLoggers.persistenceLogTarget string \"FILE\" config-api_persistence.log target global.config-api.appLoggers.scriptLogLevel string \"INFO\" config-api_script.log level global.config-api.appLoggers.scriptLogTarget string \"FILE\" config-api_script.log target global.config-api.cnCustomJavaOptions string \"\" passing custom java options to config-api. Notice you do not need to pass in any loggers options as they are introduced below in appLoggers. DO NOT PASS JAVA_OPTIONS in envs. global.config-api.configApiServerServiceName string \"config-api\" Name of the config-api service. Please keep it as default. global.config-api.enabled bool true Boolean flag to enable/disable the config-api chart. global.config-api.ingress object {\"configApiEnabled\":true} Enable endpoints in either istio or nginx ingress depending on users choice global.config-api.plugins string \"admin-ui,fido2,scim,user-mgt\" Comma-separated values of enabled plugins (supported plugins are \"admin-ui\",\"fido2\",\"scim\",\"user-mgt\",\"jans-link\",\"kc-saml\") global.config.enabled bool true Boolean flag to enable/disable the configuration chart. This normally should never be false global.configAdapterName string \"kubernetes\" The config backend adapter that will hold Gluu configuration layer. aws global.configSecretAdapter string \"kubernetes\" The config backend adapter that will hold Gluu secret layer. vault global.distribution string \"default\" Gluu distributions supported are: default global.fido2.appLoggers object {\"enableStdoutLogPrefix\":\"true\",\"fido2LogLevel\":\"INFO\",\"fido2LogTarget\":\"STDOUT\",\"persistenceDurationLogLevel\":\"INFO\",\"persistenceDurationLogTarget\":\"FILE\",\"persistenceLogLevel\":\"INFO\",\"persistenceLogTarget\":\"FILE\",\"scriptLogLevel\":\"INFO\",\"scriptLogTarget\":\"FILE\"} App loggers can be configured to define where the logs will be redirected to and the level of each in which it should be displayed. global.fido2.appLoggers.enableStdoutLogPrefix string \"true\" Enable log prefixing which enables prepending the STDOUT logs with the file name. i.e fido2 ===> 2022-12-20 17:49:55,744 INFO global.fido2.appLoggers.fido2LogLevel string \"INFO\" fido2.log level global.fido2.appLoggers.fido2LogTarget string \"STDOUT\" fido2.log target global.fido2.appLoggers.persistenceDurationLogLevel string \"INFO\" fido2_persistence_duration.log level global.fido2.appLoggers.persistenceDurationLogTarget string \"FILE\" fido2_persistence_duration.log target global.fido2.appLoggers.persistenceLogLevel string \"INFO\" fido2_persistence.log level global.fido2.appLoggers.persistenceLogTarget string \"FILE\" fido2_persistence.log target global.fido2.appLoggers.scriptLogLevel string \"INFO\" fido2_script.log level global.fido2.appLoggers.scriptLogTarget string \"FILE\" fido2_script.log target global.fido2.cnCustomJavaOptions string \"\" passing custom java options to fido2. Notice you do not need to pass in any loggers options as they are introduced below in appLoggers. DO NOT PASS JAVA_OPTIONS in envs. global.fido2.enabled bool true Boolean flag to enable/disable the fido2 chart. global.fido2.fido2ServiceName string \"fido2\" Name of the fido2 service. Please keep it as default. global.fido2.ingress object {\"fido2ConfigEnabled\":false,\"fido2Enabled\":false} Enable endpoints in either istio or nginx ingress depending on users choice global.fido2.ingress.fido2ConfigEnabled bool false Enable endpoint /.well-known/fido2-configuration global.fido2.ingress.fido2Enabled bool false Enable endpoint /jans-fido2 global.fqdn string \"demoexample.gluu.org\" Fully qualified domain name to be used for Gluu installation. This address will be used to reach Gluu services. global.gcePdStorageType string \"pd-standard\" GCE storage kind if using Google disks global.isFqdnRegistered bool false Boolean flag to enable mapping global.lbIp to global.fqdn inside pods on clouds that provide static ip for load balancers. On cloud that provide only addresses to the LB this flag will enable a script to actively scan config.configmap.lbAddr and update the hosts file inside the pods automatically. global.istio.additionalAnnotations object {} Additional annotations that will be added across the gateway in the format of global.istio.additionalLabels object {} Additional labels that will be added across the gateway in the format of global.istio.enabled bool false Boolean flag that enables using istio side-cars with Gluu services. global.istio.gateways list [] Override the gateway that can be created by default. This is used when istio ingress has already been setup and the gateway exists. global.istio.ingress bool false Boolean flag that enables using istio gateway for Gluu. This assumes istio ingress is installed and hence the LB is available. global.istio.namespace string \"istio-system\" The namespace istio is deployed in. The is normally istio-system. global.jobTtlSecondsAfterFinished int 300 https://kubernetes.io/docs/concepts/workloads/controllers/ttlafterfinished/ global.kc-scheduler.enabled bool false Boolean flag to enable/disable the kc-scheduler cronjob chart. global.kcAdminCredentialsFile string \"/etc/jans/conf/kc_admin_creds\" Path to file contains Keycloak admin credentials (username and password) global.kcDbPasswordFile string \"/etc/jans/conf/kc_db_password\" Path to file contains password for database access global.lbIp string \"22.22.22.22\" The Loadbalancer IP created by nginx or istio on clouds that provide static IPs. This is not needed if global.fqdn is globally resolvable. global.link.appLoggers object {\"enableStdoutLogPrefix\":\"true\",\"ldapStatsLogLevel\":\"INFO\",\"ldapStatsLogTarget\":\"FILE\",\"linkLogLevel\":\"INFO\",\"linkLogTarget\":\"STDOUT\",\"persistenceDurationLogLevel\":\"INFO\",\"persistenceDurationLogTarget\":\"FILE\",\"persistenceLogLevel\":\"INFO\",\"persistenceLogTarget\":\"FILE\",\"scriptLogLevel\":\"INFO\",\"scriptLogTarget\":\"FILE\"} App loggers can be configured to define where the logs will be redirected to and the level of each in which it should be displayed. global.link.appLoggers.enableStdoutLogPrefix string \"true\" Enable log prefixing which enables prepending the STDOUT logs with the file name. i.e link-persistence ===> 2022-12-20 17:49:55,744 INFO global.link.appLoggers.ldapStatsLogLevel string \"INFO\" cacherefresh_persistence_ldap_statistics.log level global.link.appLoggers.ldapStatsLogTarget string \"FILE\" cacherefresh_persistence_ldap_statistics.log target global.link.appLoggers.linkLogLevel string \"INFO\" cacherefresh.log level global.link.appLoggers.linkLogTarget string \"STDOUT\" cacherefresh.log target global.link.appLoggers.persistenceDurationLogLevel string \"INFO\" cacherefresh_persistence_duration.log level global.link.appLoggers.persistenceDurationLogTarget string \"FILE\" cacherefresh_persistence_duration.log target global.link.appLoggers.persistenceLogLevel string \"INFO\" cacherefresh_persistence.log level global.link.appLoggers.persistenceLogTarget string \"FILE\" cacherefresh_persistence.log target global.link.appLoggers.scriptLogLevel string \"INFO\" cacherefresh_script.log level global.link.appLoggers.scriptLogTarget string \"FILE\" cacherefresh_script.log target global.link.cnCustomJavaOptions string \"\" passing custom java options to link. Notice you do not need to pass in any loggers options as they are introduced below in appLoggers. DO NOT PASS JAVA_OPTIONS in envs. global.link.enabled bool false Boolean flag to enable/disable the link chart. global.link.ingress object {\"linkEnabled\":true} Enable endpoints in either istio or nginx ingress depending on users choice global.link.linkServiceName string \"link\" Name of the link service. Please keep it as default. global.nginx-ingress.enabled bool true Boolean flag to enable/disable the nginx-ingress definitions chart. global.opendj.enabled bool false Boolean flag to enable/disable the OpenDJ chart. global.opendj.ldapServiceName string \"opendj\" Name of the OpenDJ service. Please keep it as default. global.persistence.enabled bool true Boolean flag to enable/disable the persistence chart. global.saml.cnCustomJavaOptions string \"\" passing custom java options to saml. DO NOT PASS JAVA_OPTIONS in envs. global.saml.enabled bool false Boolean flag to enable/disable the saml chart. global.saml.ingress object {\"samlEnabled\":false} Enable endpoints in either istio or nginx ingress depending on users choice global.saml.samlServiceName string \"saml\" Name of the saml service. Please keep it as default. global.scim.appLoggers object {\"enableStdoutLogPrefix\":\"true\",\"ldapStatsLogLevel\":\"INFO\",\"ldapStatsLogTarget\":\"FILE\",\"persistenceDurationLogLevel\":\"INFO\",\"persistenceDurationLogTarget\":\"FILE\",\"persistenceLogLevel\":\"INFO\",\"persistenceLogTarget\":\"FILE\",\"scimLogLevel\":\"INFO\",\"scimLogTarget\":\"STDOUT\",\"scriptLogLevel\":\"INFO\",\"scriptLogTarget\":\"FILE\"} App loggers can be configured to define where the logs will be redirected to and the level of each in which it should be displayed. global.scim.appLoggers.enableStdoutLogPrefix string \"true\" Enable log prefixing which enables prepending the STDOUT logs with the file name. i.e jans-scim ===> 2022-12-20 17:49:55,744 INFO global.scim.appLoggers.ldapStatsLogLevel string \"INFO\" jans-scim_persistence_ldap_statistics.log level global.scim.appLoggers.ldapStatsLogTarget string \"FILE\" jans-scim_persistence_ldap_statistics.log target global.scim.appLoggers.persistenceDurationLogLevel string \"INFO\" jans-scim_persistence_duration.log level global.scim.appLoggers.persistenceDurationLogTarget string \"FILE\" jans-scim_persistence_duration.log target global.scim.appLoggers.persistenceLogLevel string \"INFO\" jans-scim_persistence.log level global.scim.appLoggers.persistenceLogTarget string \"FILE\" jans-scim_persistence.log target global.scim.appLoggers.scimLogLevel string \"INFO\" jans-scim.log level global.scim.appLoggers.scimLogTarget string \"STDOUT\" jans-scim.log target global.scim.appLoggers.scriptLogLevel string \"INFO\" jans-scim_script.log level global.scim.appLoggers.scriptLogTarget string \"FILE\" jans-scim_script.log target global.scim.cnCustomJavaOptions string \"\" passing custom java options to scim. Notice you do not need to pass in any loggers options as they are introduced below in appLoggers. DO NOT PASS JAVA_OPTIONS in envs. global.scim.enabled bool true Boolean flag to enable/disable the SCIM chart. global.scim.ingress object {\"scimConfigEnabled\":false,\"scimEnabled\":false} Enable endpoints in either istio or nginx ingress depending on users choice global.scim.ingress.scimConfigEnabled bool false Enable endpoint /.well-known/scim-configuration global.scim.ingress.scimEnabled bool false Enable SCIM endpoints /jans-scim global.scim.scimServiceName string \"scim\" Name of the scim service. Please keep it as default. global.storageClass object {\"allowVolumeExpansion\":true,\"allowedTopologies\":[],\"mountOptions\":[\"debug\"],\"parameters\":{},\"provisioner\":\"microk8s.io/hostpath\",\"reclaimPolicy\":\"Retain\",\"volumeBindingMode\":\"WaitForFirstConsumer\"} StorageClass section for OpenDJ charts. This is not currently used by the openbanking distribution. You may specify custom parameters as needed. global.storageClass.parameters object {} parameters: fsType: \"\" kind: \"\" pool: \"\" storageAccountType: \"\" type: \"\" global.usrEnvs object {\"normal\":{},\"secret\":{}} Add custom normal and secret envs to the service. Envs defined in global.userEnvs will be globally available to all services global.usrEnvs.normal object {} Add custom normal envs to the service. variable1: value1 global.usrEnvs.secret object {} Add custom secret envs to the service. variable1: value1 installer-settings object {\"acceptLicense\":\"\",\"aws\":{\"arn\":{\"arnAcmCert\":\"\",\"enabled\":\"\"},\"lbType\":\"\",\"vpcCidr\":\"0.0.0.0/0\"},\"confirmSettings\":false,\"couchbase\":{\"backup\":{\"fullSchedule\":\"\",\"incrementalSchedule\":\"\",\"retentionTime\":\"\",\"storageSize\":\"\"},\"clusterName\":\"\",\"commonName\":\"\",\"customFileOverride\":\"\",\"install\":\"\",\"lowResourceInstall\":\"\",\"namespace\":\"\",\"subjectAlternativeName\":\"\",\"totalNumberOfExpectedTransactionsPerSec\":\"\",\"totalNumberOfExpectedUsers\":\"\",\"volumeType\":\"\"},\"currentVersion\":\"\",\"google\":{\"useSecretManager\":\"\"},\"images\":{\"edit\":\"\"},\"ldap\":{\"backup\":{\"fullSchedule\":\"\"}},\"namespace\":\"\",\"nginxIngress\":{\"namespace\":\"\",\"releaseName\":\"\"},\"nodes\":{\"ips\":\"\",\"names\":\"\",\"zones\":\"\"},\"openbanking\":{\"cnObTransportTrustStoreP12password\":\"\",\"hasCnObTransportTrustStore\":false},\"postgres\":{\"install\":\"\",\"namespace\":\"\"},\"redis\":{\"install\":\"\",\"namespace\":\"\"},\"releaseName\":\"\",\"sql\":{\"install\":\"\",\"namespace\":\"\"},\"volumeProvisionStrategy\":\"\"} Only used by the installer. These settings do not affect nor are used by the chart kc-scheduler object {\"additionalAnnotations\":{},\"additionalLabels\":{},\"customScripts\":[],\"dnsConfig\":{},\"dnsPolicy\":\"\",\"image\":{\"pullPolicy\":\"IfNotPresent\",\"pullSecrets\":[],\"repository\":\"ghcr.io/janssenproject/jans/kc-scheduler\",\"tag\":\"1.1.6_dev\"},\"interval\":10,\"lifecycle\":{},\"resources\":{\"limits\":{\"cpu\":\"300m\",\"memory\":\"300Mi\"},\"requests\":{\"cpu\":\"300m\",\"memory\":\"300Mi\"}},\"usrEnvs\":{\"normal\":{},\"secret\":{}},\"volumeMounts\":[],\"volumes\":[]} Responsible for synchronizing Keycloak SAML clients kc-scheduler.additionalAnnotations object {} Additional annotations that will be added across the gateway in the format of kc-scheduler.additionalLabels object {} Additional labels that will be added across the gateway in the format of kc-scheduler.customScripts list [] Add custom scripts that have been mounted to run before the entrypoint. - /tmp/custom.sh - /tmp/custom2.sh kc-scheduler.dnsConfig object {} Add custom dns config kc-scheduler.dnsPolicy string \"\" Add custom dns policy kc-scheduler.image.pullPolicy string \"IfNotPresent\" Image pullPolicy to use for deploying. kc-scheduler.image.pullSecrets list [] Image Pull Secrets kc-scheduler.image.repository string \"ghcr.io/janssenproject/jans/kc-scheduler\" Image to use for deploying. kc-scheduler.image.tag string \"1.1.6_dev\" Image tag to use for deploying. kc-scheduler.interval int 10 Interval of running the scheduler (in minutes) kc-scheduler.resources object {\"limits\":{\"cpu\":\"300m\",\"memory\":\"300Mi\"},\"requests\":{\"cpu\":\"300m\",\"memory\":\"300Mi\"}} Resource specs. kc-scheduler.resources.limits.cpu string \"300m\" CPU limit. kc-scheduler.resources.limits.memory string \"300Mi\" Memory limit. kc-scheduler.resources.requests.cpu string \"300m\" CPU request. kc-scheduler.resources.requests.memory string \"300Mi\" Memory request. kc-scheduler.usrEnvs object {\"normal\":{},\"secret\":{}} Add custom normal and secret envs to the service kc-scheduler.usrEnvs.normal object {} Add custom normal envs to the service variable1: value1 kc-scheduler.usrEnvs.secret object {} Add custom secret envs to the service variable1: value1 kc-scheduler.volumeMounts list [] Configure any additional volumesMounts that need to be attached to the containers kc-scheduler.volumes list [] Configure any additional volumes that need to be attached to the pod link object {\"additionalAnnotations\":{},\"additionalLabels\":{},\"customScripts\":[],\"dnsConfig\":{},\"dnsPolicy\":\"\",\"hpa\":{\"behavior\":{},\"enabled\":true,\"maxReplicas\":10,\"metrics\":[],\"minReplicas\":1,\"targetCPUUtilizationPercentage\":50},\"image\":{\"pullPolicy\":\"IfNotPresent\",\"pullSecrets\":[],\"repository\":\"ghcr.io/janssenproject/jans/link\",\"tag\":\"1.1.6_dev\"},\"lifecycle\":{},\"livenessProbe\":{\"exec\":{\"command\":[\"python3\",\"/app/scripts/healthcheck.py\"]},\"initialDelaySeconds\":30,\"periodSeconds\":30,\"timeoutSeconds\":5},\"pdb\":{\"enabled\":true,\"maxUnavailable\":\"90%\"},\"readinessProbe\":{\"exec\":{\"command\":[\"python3\",\"/app/scripts/healthcheck.py\"]},\"initialDelaySeconds\":25,\"periodSeconds\":25,\"timeoutSeconds\":5},\"replicas\":1,\"resources\":{\"limits\":{\"cpu\":\"500m\",\"memory\":\"1200Mi\"},\"requests\":{\"cpu\":\"500m\",\"memory\":\"1200Mi\"}},\"topologySpreadConstraints\":{},\"usrEnvs\":{\"normal\":{},\"secret\":{}},\"volumeMounts\":[],\"volumes\":[]} Link. link.additionalAnnotations object {} Additional annotations that will be added across the gateway in the format of link.additionalLabels object {} Additional labels that will be added across the gateway in the format of link.customScripts list [] Add custom scripts that have been mounted to run before the entrypoint. - /tmp/custom.sh - /tmp/custom2.sh link.dnsConfig object {} Add custom dns config link.dnsPolicy string \"\" Add custom dns policy link.hpa object {\"behavior\":{},\"enabled\":true,\"maxReplicas\":10,\"metrics\":[],\"minReplicas\":1,\"targetCPUUtilizationPercentage\":50} Configure the HorizontalPodAutoscaler link.hpa.behavior object {} Scaling Policies link.hpa.metrics list [] metrics if targetCPUUtilizationPercentage is not set link.image.pullPolicy string \"IfNotPresent\" Image pullPolicy to use for deploying. link.image.pullSecrets list [] Image Pull Secrets link.image.repository string \"ghcr.io/janssenproject/jans/link\" Image to use for deploying. link.image.tag string \"1.1.6_dev\" Image tag to use for deploying. link.livenessProbe object {\"exec\":{\"command\":[\"python3\",\"/app/scripts/healthcheck.py\"]},\"initialDelaySeconds\":30,\"periodSeconds\":30,\"timeoutSeconds\":5} Configure the liveness healthcheck for the auth server if needed. link.livenessProbe.exec object {\"command\":[\"python3\",\"/app/scripts/healthcheck.py\"]} http liveness probe endpoint link.pdb object {\"enabled\":true,\"maxUnavailable\":\"90%\"} Configure the PodDisruptionBudget link.readinessProbe.exec object {\"command\":[\"python3\",\"/app/scripts/healthcheck.py\"]} http readiness probe endpoint link.replicas int 1 Service replica number. link.resources object {\"limits\":{\"cpu\":\"500m\",\"memory\":\"1200Mi\"},\"requests\":{\"cpu\":\"500m\",\"memory\":\"1200Mi\"}} Resource specs. link.resources.limits.cpu string \"500m\" CPU limit. link.resources.limits.memory string \"1200Mi\" Memory limit. This value is used to calculate memory allocation for Java. Currently it only supports Mi . Please refrain from using other units. link.resources.requests.cpu string \"500m\" CPU request. link.resources.requests.memory string \"1200Mi\" Memory request. link.topologySpreadConstraints object {} Configure the topology spread constraints. Notice this is a map NOT a list as in the upstream API https://kubernetes.io/docs/concepts/scheduling-eviction/topology-spread-constraints/ link.usrEnvs object {\"normal\":{},\"secret\":{}} Add custom normal and secret envs to the service link.usrEnvs.normal object {} Add custom normal envs to the service variable1: value1 link.usrEnvs.secret object {} Add custom secret envs to the service variable1: value1 link.volumeMounts list [] Configure any additional volumesMounts that need to be attached to the containers link.volumes list [] Configure any additional volumes that need to be attached to the pod nginx-ingress object {\"certManager\":{\"certificate\":{\"enabled\":false,\"issuerGroup\":\"cert-manager.io\",\"issuerKind\":\"ClusterIssuer\",\"issuerName\":\"\"}},\"ingress\":{\"additionalAnnotations\":{},\"additionalLabels\":{},\"adminUiAdditionalAnnotations\":{},\"adminUiLabels\":{},\"authServerAdditionalAnnotations\":{},\"authServerLabels\":{},\"authServerProtectedRegisterAdditionalAnnotations\":{},\"authServerProtectedRegisterLabels\":{},\"authServerProtectedTokenAdditionalAnnotations\":{},\"authServerProtectedTokenLabels\":{},\"casaAdditionalAnnotations\":{},\"casaLabels\":{},\"configApiAdditionalAnnotations\":{},\"configApiLabels\":{},\"deviceCodeAdditionalAnnotations\":{},\"deviceCodeLabels\":{},\"fido2AdditionalAnnotations\":{},\"fido2ConfigAdditionalAnnotations\":{},\"fido2ConfigLabels\":{},\"fido2Labels\":{},\"firebaseMessagingAdditionalAnnotations\":{},\"firebaseMessagingLabels\":{},\"hosts\":[\"demoexample.gluu.org\"],\"ingressClassName\":\"nginx\",\"openidAdditionalAnnotations\":{},\"openidConfigLabels\":{},\"path\":\"/\",\"samlAdditionalAnnotations\":{},\"samlLabels\":{},\"scimAdditionalAnnotations\":{},\"scimConfigAdditionalAnnotations\":{},\"scimConfigLabels\":{},\"scimLabels\":{},\"tls\":[{\"hosts\":[\"demoexample.gluu.org\"],\"secretName\":\"tls-certificate\"}],\"u2fAdditionalAnnotations\":{},\"u2fConfigLabels\":{},\"uma2AdditionalAnnotations\":{},\"uma2ConfigLabels\":{},\"webdiscoveryAdditionalAnnotations\":{},\"webdiscoveryLabels\":{},\"webfingerAdditionalAnnotations\":{},\"webfingerLabels\":{}}} Nginx ingress definitions chart nginx-ingress.ingress.additionalAnnotations object {} Additional annotations that will be added across all ingress definitions in the format of {cert-manager.io/issuer: \"letsencrypt-prod\"} Enable client certificate authentication nginx.ingress.kubernetes.io/auth-tls-verify-client: \"optional\" Create the secret containing the trusted ca certificates nginx.ingress.kubernetes.io/auth-tls-secret: \"gluu/tls-certificate\" Specify the verification depth in the client certificates chain nginx.ingress.kubernetes.io/auth-tls-verify-depth: \"1\" Specify if certificates are passed to upstream server nginx.ingress.kubernetes.io/auth-tls-pass-certificate-to-upstream: \"true\" nginx-ingress.ingress.additionalLabels object {} Additional labels that will be added across all ingress definitions in the format of nginx-ingress.ingress.adminUiAdditionalAnnotations object {} openid-configuration ingress resource additional annotations. nginx-ingress.ingress.adminUiLabels object {} Admin UI ingress resource labels. key app is taken. nginx-ingress.ingress.authServerAdditionalAnnotations object {} Auth server ingress resource additional annotations. nginx-ingress.ingress.authServerLabels object {} Auth server ingress resource labels. key app is taken nginx-ingress.ingress.authServerProtectedRegisterAdditionalAnnotations object {} Auth server protected register ingress resource additional annotations. nginx-ingress.ingress.authServerProtectedRegisterLabels object {} Auth server protected token ingress resource labels. key app is taken nginx-ingress.ingress.authServerProtectedTokenAdditionalAnnotations object {} Auth server protected token ingress resource additional annotations. nginx-ingress.ingress.authServerProtectedTokenLabels object {} Auth server protected token ingress resource labels. key app is taken nginx-ingress.ingress.casaAdditionalAnnotations object {} Casa ingress resource additional annotations. nginx-ingress.ingress.casaLabels object {} Casa ingress resource labels. key app is taken nginx-ingress.ingress.configApiAdditionalAnnotations object {} ConfigAPI ingress resource additional annotations. nginx-ingress.ingress.configApiLabels object {} configAPI ingress resource labels. key app is taken nginx-ingress.ingress.deviceCodeAdditionalAnnotations object {} device-code ingress resource additional annotations. nginx-ingress.ingress.deviceCodeLabels object {} device-code ingress resource labels. key app is taken nginx-ingress.ingress.fido2AdditionalAnnotations object {} fido2 ingress resource additional annotations. nginx-ingress.ingress.fido2ConfigAdditionalAnnotations object {} fido2 config ingress resource additional annotations. nginx-ingress.ingress.fido2ConfigLabels object {} fido2 config ingress resource labels. key app is taken nginx-ingress.ingress.fido2Labels object {} fido2 ingress resource labels. key app is taken nginx-ingress.ingress.firebaseMessagingAdditionalAnnotations object {} Firebase Messaging ingress resource additional annotations. nginx-ingress.ingress.firebaseMessagingLabels object {} Firebase Messaging ingress resource labels. key app is taken nginx-ingress.ingress.openidAdditionalAnnotations object {} openid-configuration ingress resource additional annotations. nginx-ingress.ingress.openidConfigLabels object {} openid-configuration ingress resource labels. key app is taken nginx-ingress.ingress.samlAdditionalAnnotations object {} SAML ingress resource additional annotations. nginx-ingress.ingress.samlLabels object {} SAML config ingress resource labels. key app is taken nginx-ingress.ingress.scimAdditionalAnnotations object {} SCIM ingress resource additional annotations. nginx-ingress.ingress.scimConfigAdditionalAnnotations object {} SCIM config ingress resource additional annotations. nginx-ingress.ingress.scimConfigLabels object {} SCIM config ingress resource labels. key app is taken nginx-ingress.ingress.scimLabels object {} SCIM config ingress resource labels. key app is taken nginx-ingress.ingress.tls list [{\"hosts\":[\"demoexample.gluu.org\"],\"secretName\":\"tls-certificate\"}] Secrets holding HTTPS CA cert and key. nginx-ingress.ingress.u2fAdditionalAnnotations object {} u2f config ingress resource additional annotations. nginx-ingress.ingress.u2fConfigLabels object {} u2f config ingress resource labels. key app is taken nginx-ingress.ingress.uma2AdditionalAnnotations object {} uma2 config ingress resource additional annotations. nginx-ingress.ingress.uma2ConfigLabels object {} uma2 config ingress resource labels. key app is taken nginx-ingress.ingress.webdiscoveryAdditionalAnnotations object {} webdiscovery ingress resource additional annotations. nginx-ingress.ingress.webdiscoveryLabels object {} webdiscovery ingress resource labels. key app is taken nginx-ingress.ingress.webfingerAdditionalAnnotations object {} webfinger ingress resource additional annotations. nginx-ingress.ingress.webfingerLabels object {} webfinger ingress resource labels. key app is taken opendj object {\"additionalAnnotations\":{},\"additionalLabels\":{},\"backup\":{\"cronJobSchedule\":\"*/59 * * * *\",\"enabled\":true},\"customScripts\":[],\"dnsConfig\":{},\"dnsPolicy\":\"\",\"hpa\":{\"behavior\":{},\"enabled\":true,\"maxReplicas\":10,\"metrics\":[],\"minReplicas\":1,\"targetCPUUtilizationPercentage\":50},\"image\":{\"pullPolicy\":\"IfNotPresent\",\"pullSecrets\":[],\"repository\":\"gluufederation/opendj\",\"tag\":\"5.0.0_dev\"},\"lifecycle\":{\"preStop\":{\"exec\":{\"command\":[\"/bin/sh\",\"-c\",\"python3 /app/scripts/deregister_peer.py 1>&/proc/1/fd/1\"]}}},\"livenessProbe\":{\"exec\":{\"command\":[\"python3\",\"/app/scripts/healthcheck.py\"]},\"failureThreshold\":20,\"initialDelaySeconds\":30,\"periodSeconds\":30,\"timeoutSeconds\":5},\"pdb\":{\"enabled\":true,\"maxUnavailable\":1},\"persistence\":{\"size\":\"5Gi\"},\"ports\":{\"tcp-admin\":{\"nodePort\":\"\",\"port\":4444,\"protocol\":\"TCP\",\"targetPort\":4444},\"tcp-ldap\":{\"nodePort\":\"\",\"port\":1389,\"protocol\":\"TCP\",\"targetPort\":1389},\"tcp-ldaps\":{\"nodePort\":\"\",\"port\":1636,\"protocol\":\"TCP\",\"targetPort\":1636},\"tcp-repl\":{\"nodePort\":\"\",\"port\":8989,\"protocol\":\"TCP\",\"targetPort\":8989},\"tcp-serf\":{\"nodePort\":\"\",\"port\":7946,\"protocol\":\"TCP\",\"targetPort\":7946},\"udp-serf\":{\"nodePort\":\"\",\"port\":7946,\"protocol\":\"UDP\",\"targetPort\":7946}},\"readinessProbe\":{\"failureThreshold\":20,\"initialDelaySeconds\":60,\"periodSeconds\":25,\"tcpSocket\":{\"port\":1636},\"timeoutSeconds\":5},\"replicas\":1,\"resources\":{\"limits\":{\"cpu\":\"1500m\",\"memory\":\"2000Mi\"},\"requests\":{\"cpu\":\"1500m\",\"memory\":\"2000Mi\"}},\"topologySpreadConstraints\":{},\"usrEnvs\":{\"normal\":{},\"secret\":{}},\"volumeMounts\":[],\"volumes\":[]} OpenDJ is a directory server which implements a wide range of Lightweight Directory Access Protocol and related standards, including full compliance with LDAPv3 but also support for Directory Service Markup Language (DSMLv2).Written in Java, OpenDJ offers multi-master replication, access control, and many extensions. opendj.additionalAnnotations object {} Additional annotations that will be added across the gateway in the format of opendj.additionalLabels object {} Additional labels that will be added across the gateway in the format of opendj.backup object {\"cronJobSchedule\":\"*/59 * * * *\",\"enabled\":true} Configure ldap backup cronjob opendj.customScripts list [] Add custom scripts that have been mounted to run before the entrypoint. - /tmp/custom.sh - /tmp/custom2.sh opendj.dnsConfig object {} Add custom dns config opendj.dnsPolicy string \"\" Add custom dns policy opendj.hpa object {\"behavior\":{},\"enabled\":true,\"maxReplicas\":10,\"metrics\":[],\"minReplicas\":1,\"targetCPUUtilizationPercentage\":50} Configure the HorizontalPodAutoscaler opendj.hpa.behavior object {} Scaling Policies opendj.hpa.metrics list [] metrics if targetCPUUtilizationPercentage is not set opendj.image.pullPolicy string \"IfNotPresent\" Image pullPolicy to use for deploying. opendj.image.pullSecrets list [] Image Pull Secrets opendj.image.repository string \"gluufederation/opendj\" Image to use for deploying. opendj.image.tag string \"5.0.0_dev\" Image tag to use for deploying. opendj.livenessProbe object {\"exec\":{\"command\":[\"python3\",\"/app/scripts/healthcheck.py\"]},\"failureThreshold\":20,\"initialDelaySeconds\":30,\"periodSeconds\":30,\"timeoutSeconds\":5} Configure the liveness healthcheck for OpenDJ if needed. https://github.com/GluuFederation/docker-opendj/blob/master/scripts/healthcheck.py opendj.livenessProbe.exec object {\"command\":[\"python3\",\"/app/scripts/healthcheck.py\"]} Executes the python3 healthcheck. opendj.pdb object {\"enabled\":true,\"maxUnavailable\":1} Configure the PodDisruptionBudget opendj.persistence.size string \"5Gi\" OpenDJ volume size opendj.readinessProbe object {\"failureThreshold\":20,\"initialDelaySeconds\":60,\"periodSeconds\":25,\"tcpSocket\":{\"port\":1636},\"timeoutSeconds\":5} Configure the readiness healthcheck for OpenDJ if needed. https://github.com/GluuFederation/docker-opendj/blob/master/scripts/healthcheck.py opendj.replicas int 1 Service replica number. opendj.resources object {\"limits\":{\"cpu\":\"1500m\",\"memory\":\"2000Mi\"},\"requests\":{\"cpu\":\"1500m\",\"memory\":\"2000Mi\"}} Resource specs. opendj.resources.limits.cpu string \"1500m\" CPU limit. opendj.resources.limits.memory string \"2000Mi\" Memory limit. opendj.resources.requests.cpu string \"1500m\" CPU request. opendj.resources.requests.memory string \"2000Mi\" Memory request. opendj.topologySpreadConstraints object {} Configure the topology spread constraints. Notice this is a map NOT a list as in the upstream API https://kubernetes.io/docs/concepts/scheduling-eviction/topology-spread-constraints/ opendj.usrEnvs object {\"normal\":{},\"secret\":{}} Add custom normal and secret envs to the service opendj.usrEnvs.normal object {} Add custom normal envs to the service variable1: value1 opendj.usrEnvs.secret object {} Add custom secret envs to the service variable1: value1 opendj.volumeMounts list [] Configure any additional volumesMounts that need to be attached to the containers opendj.volumes list [] Configure any additional volumes that need to be attached to the pod persistence object {\"additionalAnnotations\":{},\"additionalLabels\":{},\"customScripts\":[],\"dnsConfig\":{},\"dnsPolicy\":\"\",\"image\":{\"pullPolicy\":\"IfNotPresent\",\"pullSecrets\":[],\"repository\":\"ghcr.io/janssenproject/jans/persistence-loader\",\"tag\":\"1.1.6_dev\"},\"lifecycle\":{},\"resources\":{\"limits\":{\"cpu\":\"300m\",\"memory\":\"300Mi\"},\"requests\":{\"cpu\":\"300m\",\"memory\":\"300Mi\"}},\"usrEnvs\":{\"normal\":{},\"secret\":{}},\"volumeMounts\":[],\"volumes\":[]} Job to generate data and initial config for Gluu Server persistence layer. persistence.additionalAnnotations object {} Additional annotations that will be added across the gateway in the format of persistence.additionalLabels object {} Additional labels that will be added across the gateway in the format of persistence.customScripts list [] Add custom scripts that have been mounted to run before the entrypoint. - /tmp/custom.sh - /tmp/custom2.sh persistence.dnsConfig object {} Add custom dns config persistence.dnsPolicy string \"\" Add custom dns policy persistence.image.pullPolicy string \"IfNotPresent\" Image pullPolicy to use for deploying. persistence.image.pullSecrets list [] Image Pull Secrets persistence.image.repository string \"ghcr.io/janssenproject/jans/persistence-loader\" Image to use for deploying. persistence.image.tag string \"1.1.6_dev\" Image tag to use for deploying. persistence.resources object {\"limits\":{\"cpu\":\"300m\",\"memory\":\"300Mi\"},\"requests\":{\"cpu\":\"300m\",\"memory\":\"300Mi\"}} Resource specs. persistence.resources.limits.cpu string \"300m\" CPU limit persistence.resources.limits.memory string \"300Mi\" Memory limit. persistence.resources.requests.cpu string \"300m\" CPU request. persistence.resources.requests.memory string \"300Mi\" Memory request. persistence.usrEnvs object {\"normal\":{},\"secret\":{}} Add custom normal and secret envs to the service persistence.usrEnvs.normal object {} Add custom normal envs to the service variable1: value1 persistence.usrEnvs.secret object {} Add custom secret envs to the service variable1: value1 persistence.volumeMounts list [] Configure any additional volumesMounts that need to be attached to the containers persistence.volumes list [] Configure any additional volumes that need to be attached to the pod saml object {\"additionalAnnotations\":{},\"additionalLabels\":{},\"customScripts\":[],\"dnsConfig\":{},\"dnsPolicy\":\"\",\"hpa\":{\"behavior\":{},\"enabled\":true,\"maxReplicas\":10,\"metrics\":[],\"minReplicas\":1,\"targetCPUUtilizationPercentage\":50},\"image\":{\"pullPolicy\":\"IfNotPresent\",\"pullSecrets\":[],\"repository\":\"ghcr.io/janssenproject/jans/saml\",\"tag\":\"1.1.6_dev\"},\"lifecycle\":{},\"livenessProbe\":{\"exec\":{\"command\":[\"python3\",\"/app/scripts/healthcheck.py\"]},\"failureThreshold\":10,\"initialDelaySeconds\":30,\"periodSeconds\":30,\"timeoutSeconds\":5},\"pdb\":{\"enabled\":true,\"maxUnavailable\":\"90%\"},\"readinessProbe\":{\"exec\":{\"command\":[\"python3\",\"/app/scripts/healthcheck.py\"]},\"failureThreshold\":10,\"initialDelaySeconds\":25,\"periodSeconds\":25,\"timeoutSeconds\":5},\"replicas\":1,\"resources\":{\"limits\":{\"cpu\":\"500m\",\"memory\":\"1200Mi\"},\"requests\":{\"cpu\":\"500m\",\"memory\":\"1200Mi\"}},\"topologySpreadConstraints\":{},\"usrEnvs\":{\"normal\":{},\"secret\":{}},\"volumeMounts\":[],\"volumes\":[]} SAML. saml.additionalAnnotations object {} Additional annotations that will be added across the gateway in the format of saml.additionalLabels object {} Additional labels that will be added across the gateway in the format of saml.customScripts list [] Add custom scripts that have been mounted to run before the entrypoint. - /tmp/custom.sh - /tmp/custom2.sh saml.dnsConfig object {} Add custom dns config saml.dnsPolicy string \"\" Add custom dns policy saml.hpa object {\"behavior\":{},\"enabled\":true,\"maxReplicas\":10,\"metrics\":[],\"minReplicas\":1,\"targetCPUUtilizationPercentage\":50} Configure the HorizontalPodAutoscaler saml.hpa.behavior object {} Scaling Policies saml.hpa.metrics list [] metrics if targetCPUUtilizationPercentage is not set saml.image.pullPolicy string \"IfNotPresent\" Image pullPolicy to use for deploying. saml.image.pullSecrets list [] Image Pull Secrets saml.image.repository string \"ghcr.io/janssenproject/jans/saml\" Image to use for deploying. saml.image.tag string \"1.1.6_dev\" Image tag to use for deploying. saml.livenessProbe object {\"exec\":{\"command\":[\"python3\",\"/app/scripts/healthcheck.py\"]},\"failureThreshold\":10,\"initialDelaySeconds\":30,\"periodSeconds\":30,\"timeoutSeconds\":5} Configure the liveness healthcheck for the auth server if needed. saml.livenessProbe.exec object {\"command\":[\"python3\",\"/app/scripts/healthcheck.py\"]} http liveness probe endpoint saml.pdb object {\"enabled\":true,\"maxUnavailable\":\"90%\"} Configure the PodDisruptionBudget saml.readinessProbe.exec object {\"command\":[\"python3\",\"/app/scripts/healthcheck.py\"]} http readiness probe endpoint saml.replicas int 1 Service replica number. saml.resources object {\"limits\":{\"cpu\":\"500m\",\"memory\":\"1200Mi\"},\"requests\":{\"cpu\":\"500m\",\"memory\":\"1200Mi\"}} Resource specs. saml.resources.limits.cpu string \"500m\" CPU limit. saml.resources.limits.memory string \"1200Mi\" Memory limit. This value is used to calculate memory allocation for Java. Currently it only supports Mi . Please refrain from using other units. saml.resources.requests.cpu string \"500m\" CPU request. saml.resources.requests.memory string \"1200Mi\" Memory request. saml.topologySpreadConstraints object {} Configure the topology spread constraints. Notice this is a map NOT a list as in the upstream API https://kubernetes.io/docs/concepts/scheduling-eviction/topology-spread-constraints/ saml.usrEnvs object {\"normal\":{},\"secret\":{}} Add custom normal and secret envs to the service saml.usrEnvs.normal object {} Add custom normal envs to the service variable1: value1 saml.usrEnvs.secret object {} Add custom secret envs to the service variable1: value1 saml.volumeMounts list [] Configure any additional volumesMounts that need to be attached to the containers saml.volumes list [] Configure any additional volumes that need to be attached to the pod scim object {\"additionalAnnotations\":{},\"additionalLabels\":{},\"customScripts\":[],\"dnsConfig\":{},\"dnsPolicy\":\"\",\"hpa\":{\"behavior\":{},\"enabled\":true,\"maxReplicas\":10,\"metrics\":[],\"minReplicas\":1,\"targetCPUUtilizationPercentage\":50},\"image\":{\"pullPolicy\":\"IfNotPresent\",\"pullSecrets\":[],\"repository\":\"ghcr.io/janssenproject/jans/scim\",\"tag\":\"1.1.6_dev\"},\"lifecycle\":{},\"livenessProbe\":{\"httpGet\":{\"path\":\"/jans-scim/sys/health-check\",\"port\":8080},\"initialDelaySeconds\":30,\"periodSeconds\":30,\"timeoutSeconds\":5},\"pdb\":{\"enabled\":true,\"maxUnavailable\":\"90%\"},\"readinessProbe\":{\"httpGet\":{\"path\":\"/jans-scim/sys/health-check\",\"port\":8080},\"initialDelaySeconds\":25,\"periodSeconds\":25,\"timeoutSeconds\":5},\"replicas\":1,\"resources\":{\"limits\":{\"cpu\":\"1000m\",\"memory\":\"1200Mi\"},\"requests\":{\"cpu\":\"1000m\",\"memory\":\"1200Mi\"}},\"service\":{\"name\":\"http-scim\",\"port\":8080},\"topologySpreadConstraints\":{},\"usrEnvs\":{\"normal\":{},\"secret\":{}},\"volumeMounts\":[],\"volumes\":[]} System for Cross-domain Identity Management (SCIM) version 2.0 scim.additionalAnnotations object {} Additional annotations that will be added across the gateway in the format of scim.additionalLabels object {} Additional labels that will be added across the gateway in the format of scim.customScripts list [] Add custom scripts that have been mounted to run before the entrypoint. - /tmp/custom.sh - /tmp/custom2.sh scim.dnsConfig object {} Add custom dns config scim.dnsPolicy string \"\" Add custom dns policy scim.hpa object {\"behavior\":{},\"enabled\":true,\"maxReplicas\":10,\"metrics\":[],\"minReplicas\":1,\"targetCPUUtilizationPercentage\":50} Configure the HorizontalPodAutoscaler scim.hpa.behavior object {} Scaling Policies scim.hpa.metrics list [] metrics if targetCPUUtilizationPercentage is not set scim.image.pullPolicy string \"IfNotPresent\" Image pullPolicy to use for deploying. scim.image.pullSecrets list [] Image Pull Secrets scim.image.repository string \"ghcr.io/janssenproject/jans/scim\" Image to use for deploying. scim.image.tag string \"1.1.6_dev\" Image tag to use for deploying. scim.livenessProbe object {\"httpGet\":{\"path\":\"/jans-scim/sys/health-check\",\"port\":8080},\"initialDelaySeconds\":30,\"periodSeconds\":30,\"timeoutSeconds\":5} Configure the liveness healthcheck for SCIM if needed. scim.livenessProbe.httpGet.path string \"/jans-scim/sys/health-check\" http liveness probe endpoint scim.pdb object {\"enabled\":true,\"maxUnavailable\":\"90%\"} Configure the PodDisruptionBudget scim.readinessProbe object {\"httpGet\":{\"path\":\"/jans-scim/sys/health-check\",\"port\":8080},\"initialDelaySeconds\":25,\"periodSeconds\":25,\"timeoutSeconds\":5} Configure the readiness healthcheck for the SCIM if needed. scim.readinessProbe.httpGet.path string \"/jans-scim/sys/health-check\" http readiness probe endpoint scim.replicas int 1 Service replica number. scim.resources.limits.cpu string \"1000m\" CPU limit. scim.resources.limits.memory string \"1200Mi\" Memory limit. This value is used to calculate memory allocation for Java. Currently it only supports Mi . Please refrain from using other units. scim.resources.requests.cpu string \"1000m\" CPU request. scim.resources.requests.memory string \"1200Mi\" Memory request. scim.service.name string \"http-scim\" The name of the scim port within the scim service. Please keep it as default. scim.service.port int 8080 Port of the scim service. Please keep it as default. scim.topologySpreadConstraints object {} Configure the topology spread constraints. Notice this is a map NOT a list as in the upstream API https://kubernetes.io/docs/concepts/scheduling-eviction/topology-spread-constraints/ scim.usrEnvs object {\"normal\":{},\"secret\":{}} Add custom normal and secret envs to the service scim.usrEnvs.normal object {} Add custom normal envs to the service variable1: value1 scim.usrEnvs.secret object {} Add custom secret envs to the service variable1: value1 scim.volumeMounts list [] Configure any additional volumesMounts that need to be attached to the containers scim.volumes list [] Configure any additional volumes that need to be attached to the pod Autogenerated from chart metadata using helm-docs v1.13.1","title":"Values"},{"location":"supergluu/","tags":["Super Gluu","Introduction"],"text":"Super Gluu Documentation # Super Gluu is a free and secure two-factor authentication (2FA) mobile app. Super Gluu app can be used to achieve 2FA for web and mobile applications with Janssen Server , Gluu Flex , and Gluu Server working as authentication servers. Super Gluu documentation is organized into the following sections: User Guide Admin Guide Developer Guide Compatibility # Super Gluu is compatible with all versions of Gluu Flex. FIDO Security # During Super Gluu authentication, the Gluu Flex does more than look at the device ID to grant access. Super Gluu uses the Gluu Flex Server's FIDO U2F endpoints to enroll a public key. The private key is stored on the device. At authentication time, the Gluu Flex sends a challenge-response to the device to check for the corresponding private key. This adds an extra layer of security to Super Gluu push notification authentications. How to Use Super Gluu # Super Gluu is tightly bundled with Janssen. Follow the Flex installation guide to deploy Gluu Flex, then follow the Super Gluu admin guide to configure and begin using Super Gluu for strong authentication. Workflows # Super Gluu supports multiple workflows, including: A one-step, passwordless authentication, where the person scans a QR code with their Super Gluu app and the Gluu Flex looks up which person is associated with that device. A two-step authentication, where the person enters their username and then receives an out-of-band push notification to the mobile device to authorize access (a.k.a identifier first authentication). A two-step authentication, where the person enters their username and password and then receives an out-of-band push notification to the mobile device to authorize access. In all scenarios, users are prompted to scan a QR code on their first Super Gluu authentication to bind their device and account. In the second and third workflows listed above, users begin receiving push notifications for all authentications after the initial device registration process. Testing locally # Super Gluu security is based on SSL and therefore expects a public server with valid certificates. To test locally on a non-public server, follow these steps Download Super Gluu # Super Gluu is available for free on the iOS and Android app marketplaces! Download the Android app Download the iOS app Contributors # The next version of Super Gluu will support localization in many languages. We'd like to extend our sincere appreciation to the following people for helping translate Super Gluu content: Jose Gonzalez, Gluu Gasmyr Mougang, Gluu Yumi Sano, iBridge Andrea Patricelli, Tirasa Yuriy Zabrovarrnay, Gluu Aliaksander Sameseu, Gluu Andre Koot, Nixu Mohammad Abudayyeh, Gluu Ganesh Dutt Sharma, Gluu Mohib Zico, Gluu Mustafa Baser, Gluu","title":"Super Gluu Documentation"},{"location":"supergluu/#super-gluu-documentation","text":"Super Gluu is a free and secure two-factor authentication (2FA) mobile app. Super Gluu app can be used to achieve 2FA for web and mobile applications with Janssen Server , Gluu Flex , and Gluu Server working as authentication servers. Super Gluu documentation is organized into the following sections: User Guide Admin Guide Developer Guide","title":"Super Gluu Documentation"},{"location":"supergluu/#compatibility","text":"Super Gluu is compatible with all versions of Gluu Flex.","title":"Compatibility"},{"location":"supergluu/#fido-security","text":"During Super Gluu authentication, the Gluu Flex does more than look at the device ID to grant access. Super Gluu uses the Gluu Flex Server's FIDO U2F endpoints to enroll a public key. The private key is stored on the device. At authentication time, the Gluu Flex sends a challenge-response to the device to check for the corresponding private key. This adds an extra layer of security to Super Gluu push notification authentications.","title":"FIDO Security"},{"location":"supergluu/#how-to-use-super-gluu","text":"Super Gluu is tightly bundled with Janssen. Follow the Flex installation guide to deploy Gluu Flex, then follow the Super Gluu admin guide to configure and begin using Super Gluu for strong authentication.","title":"How to Use Super Gluu"},{"location":"supergluu/#workflows","text":"Super Gluu supports multiple workflows, including: A one-step, passwordless authentication, where the person scans a QR code with their Super Gluu app and the Gluu Flex looks up which person is associated with that device. A two-step authentication, where the person enters their username and then receives an out-of-band push notification to the mobile device to authorize access (a.k.a identifier first authentication). A two-step authentication, where the person enters their username and password and then receives an out-of-band push notification to the mobile device to authorize access. In all scenarios, users are prompted to scan a QR code on their first Super Gluu authentication to bind their device and account. In the second and third workflows listed above, users begin receiving push notifications for all authentications after the initial device registration process.","title":"Workflows"},{"location":"supergluu/#testing-locally","text":"Super Gluu security is based on SSL and therefore expects a public server with valid certificates. To test locally on a non-public server, follow these steps","title":"Testing locally"},{"location":"supergluu/#download-super-gluu","text":"Super Gluu is available for free on the iOS and Android app marketplaces! Download the Android app Download the iOS app","title":"Download Super Gluu"},{"location":"supergluu/#contributors","text":"The next version of Super Gluu will support localization in many languages. We'd like to extend our sincere appreciation to the following people for helping translate Super Gluu content: Jose Gonzalez, Gluu Gasmyr Mougang, Gluu Yumi Sano, iBridge Andrea Patricelli, Tirasa Yuriy Zabrovarrnay, Gluu Aliaksander Sameseu, Gluu Andre Koot, Nixu Mohammad Abudayyeh, Gluu Ganesh Dutt Sharma, Gluu Mohib Zico, Gluu Mustafa Baser, Gluu","title":"Contributors"},{"location":"supergluu/admin-guide/","tags":["Super Gluu","administration","configuration"],"text":"Super Gluu Administration Guide # Obtaining an SSA # In order to set up Super Gluu, the administrator must obtain a Software Statement Assertion from Agama Lab . Login with GitHub or email, then sign up for a SCAN subscription. The free tier will give you 500 credits, which can be used for 500 SuperGluu API calls (1 call = 1 credit). Then, go over to the SSA tab and create a new SSA with the supergluu software role and an expiry date of your choice. Your SSA will no longer be useable after that date. After creating the SSA, you can click on Details and view the base64 encoded string of characters that represent the SSA. You will need this string during setup. Configuration on Gluu Flex # Log into Flex UI Navigate to Admin > Scripts > super_gluu Use the following properties: AS_SSA : Your base64 encoded SSA string from Agama Lab AS_ENDPOINT : https://account.gluu.org The rest of the values can be left as provided Enable super_gluu script Navigate to FIDO and Enable SuperGluu At this point, the Super Gluu module on Gluu Flex is configured and ready. This means that, using OpenID Connect acr_values , applications can now request Super Gluu authentication for users. You can verify this by going to the super_gluu script properties and seeing that the AS_CLIENT_ID and AS_CLIENT_SECRET fields are now populated. Configuration on Gluu Server 4.x # To get started, log into the Gluu Server dashboard (a.k.a. oxTrust) and do the following: Navigate to Configuration > Manage Custom Scripts . In the Person Authentication tab find the super_gluu authentication module. Use the following properties: AS_SSA : Your base64 encoded SSA string from Agama Lab AS_ENDPOINT : https://account.gluu.org The rest of the values can be left as provided Scroll down and find the Enable check box. Enable the script by clicking the check box. Scroll to the bottom of the page and click Update . Now Super Gluu is an available authentication mechanism for your Gluu Server. This means that, using OpenID Connect acr_values , applications can now request Super Gluu authentication for users. You can verify this by going to the super_gluu script properties and seeing that the AS_CLIENT_ID and AS_CLIENT_SECRET fields are now populated. Migration from old setups # If you are using a setup from before SCAN was implemented, you will need to migrate to the latest super_gluu interception script. Obtain the latest super_gluu interception script for Gluu Server or Jans Open the script configuration using one of the methods mentioned above, and navigate to super_gluu Replace the contents of the script with the new one Disable the script, and click Update . This will update the properties of the script configuration. Populate the AS_SSA and AS_ENDPOINT fields as described above. Enable the script by clicking the Enable check box Scroll to the bottom of the page and click Update The latest version of Super Gluu is now enabled on your server. Note To make sure Super Gluu has been enabled successfully, you can check your Gluu Server's OpenID Connect configuration by navigating to the following URL: https:///.well-known/openid-configuration . Find acr_values_supported and you should see super_gluu . Test 2FA Authentication Flow # To test the Super Gluu configuration from end to end, an administrator can follow the steps below: Change the default authentication method to super_gluu using this guide Keep this browser window active so you can revert the authentication method to the default one. Prepare your mobile device by following Super Gluu mobile app user guide Perform tests using a test user","title":"Administration Guide"},{"location":"supergluu/admin-guide/#super-gluu-administration-guide","text":"","title":"Super Gluu Administration Guide"},{"location":"supergluu/admin-guide/#obtaining-an-ssa","text":"In order to set up Super Gluu, the administrator must obtain a Software Statement Assertion from Agama Lab . Login with GitHub or email, then sign up for a SCAN subscription. The free tier will give you 500 credits, which can be used for 500 SuperGluu API calls (1 call = 1 credit). Then, go over to the SSA tab and create a new SSA with the supergluu software role and an expiry date of your choice. Your SSA will no longer be useable after that date. After creating the SSA, you can click on Details and view the base64 encoded string of characters that represent the SSA. You will need this string during setup.","title":"Obtaining an SSA"},{"location":"supergluu/admin-guide/#configuration-on-gluu-flex","text":"Log into Flex UI Navigate to Admin > Scripts > super_gluu Use the following properties: AS_SSA : Your base64 encoded SSA string from Agama Lab AS_ENDPOINT : https://account.gluu.org The rest of the values can be left as provided Enable super_gluu script Navigate to FIDO and Enable SuperGluu At this point, the Super Gluu module on Gluu Flex is configured and ready. This means that, using OpenID Connect acr_values , applications can now request Super Gluu authentication for users. You can verify this by going to the super_gluu script properties and seeing that the AS_CLIENT_ID and AS_CLIENT_SECRET fields are now populated.","title":"Configuration on Gluu Flex"},{"location":"supergluu/admin-guide/#configuration-on-gluu-server-4x","text":"To get started, log into the Gluu Server dashboard (a.k.a. oxTrust) and do the following: Navigate to Configuration > Manage Custom Scripts . In the Person Authentication tab find the super_gluu authentication module. Use the following properties: AS_SSA : Your base64 encoded SSA string from Agama Lab AS_ENDPOINT : https://account.gluu.org The rest of the values can be left as provided Scroll down and find the Enable check box. Enable the script by clicking the check box. Scroll to the bottom of the page and click Update . Now Super Gluu is an available authentication mechanism for your Gluu Server. This means that, using OpenID Connect acr_values , applications can now request Super Gluu authentication for users. You can verify this by going to the super_gluu script properties and seeing that the AS_CLIENT_ID and AS_CLIENT_SECRET fields are now populated.","title":"Configuration on Gluu Server 4.x"},{"location":"supergluu/admin-guide/#migration-from-old-setups","text":"If you are using a setup from before SCAN was implemented, you will need to migrate to the latest super_gluu interception script. Obtain the latest super_gluu interception script for Gluu Server or Jans Open the script configuration using one of the methods mentioned above, and navigate to super_gluu Replace the contents of the script with the new one Disable the script, and click Update . This will update the properties of the script configuration. Populate the AS_SSA and AS_ENDPOINT fields as described above. Enable the script by clicking the Enable check box Scroll to the bottom of the page and click Update The latest version of Super Gluu is now enabled on your server. Note To make sure Super Gluu has been enabled successfully, you can check your Gluu Server's OpenID Connect configuration by navigating to the following URL: https:///.well-known/openid-configuration . Find acr_values_supported and you should see super_gluu .","title":"Migration from old setups"},{"location":"supergluu/admin-guide/#test-2fa-authentication-flow","text":"To test the Super Gluu configuration from end to end, an administrator can follow the steps below: Change the default authentication method to super_gluu using this guide Keep this browser window active so you can revert the authentication method to the default one. Prepare your mobile device by following Super Gluu mobile app user guide Perform tests using a test user","title":"Test 2FA Authentication Flow"},{"location":"supergluu/developer-guide/","tags":["Super Gluu","Developer"],"text":"Super Gluu Developer Guide # Super Gluu is a two-factor authentication mobile application for iOS and Android. Super Gluu can be used as a strong authentication mechanism to access resources that are protected by Gluu's free open source central authentication server, called the Gluu Server . The below documentation describes what is happening during user enrollment and authentication. QR Code # During enrollment and authentication, the app goes through a few steps: The user scans the QR code, which contains identification data in the following format: { \"app\" : \"https://example.gluu.org\", \"state\" : \"dek4nwk6-dk56-sr43-4frt-4jfi30fltimd\" \"issuer\" : \"https://example.gluu.org\" \"created\" : \"2016-06-12T12:00:01.874000\" } Data from the QR code is changed into Fido U2F metadata: String discoveryUrl = oxPush2Request.getIssuer(); discoveryUrl += \"/.well-known/fido-u2f-configuration\"; final String discoveryJson = CommunicationService.get(discoveryUrl, null); final U2fMetaData u2fMetaData = new Gson().fromJson(discoveryJson, U2fMetaData.class); This metadata is sent to the server: ``` final List keyHandles = dataStore.getKeyHandlesByIssuerAndAppId(oxPush2Request.getIssuer(), oxPush2Request.getApp()); final boolean isEnroll = (keyHandles.size() == 0) || StringUtils.equals(oxPush2Request.getMethod(), \"enroll\"); final String u2fEndpoint; if (isEnroll) u2fEndpoint = u2fMetaData.getRegistrationEndpoint();// if enroll then get registration endpoint } else { u2fEndpoint = u2fMetaData.getAuthenticationEndpoint();// if authentication then get corresponding endpoint } validChallengeJsonResponse = CommunicationService.get(u2fEndpoint, parameters); ``` When the result comes back, it decides whether to enroll a new device or authenticate an existing one: if (isEnroll) { tokenResponse = oxPush2RequestListener.onEnroll(challengeJson, oxPush2Request, isDeny); } else { tokenResponse = oxPush2RequestListener.onSign(challengeJson, u2fMetaData.getIssuer(), isDeny); } Enrollment Process # If you scan a QR code for the first time and your device's UDID isn't attached to your user ID, the app will enroll it. First, it needs to prepare the data properties, as follows: > String version = request.getString(JSON_PROPERTY_VERSION); > String appParam = request.getString(JSON_PROPERTY_APP_ID); > String challenge = request.getString(JSON_PROPERTY_SERVER_CHALLENGE); > String origin = oxPush2Request.getIssuer(); > > EnrollmentResponse enrollmentResponse = u2fKey.register(new EnrollmentRequest(version, appParam, challenge, oxPush2Request)); During registration, the app generates a unique keyHandle and keyPair (public/private keys) to sign all data and uses an ECC algorithm to encode the required data, as follows: > TokenEntry tokenEntry = new TokenEntry(keyPairGenerator.keyPairToJson(keyPair), enrollmentRequest.getApplication(), enrollmentRequest.getOxPush2Request().getIssuer()); > . > . > . > dataStore.storeTokenEntry(keyHandle, tokenEntry); > byte[] userPublicKey = keyPairGenerator.encodePublicKey(keyPair.getPublic()); > > byte[] applicationSha256 = DigestUtils.sha256(application); > byte[] challengeSha256 = DigestUtils.sha256(challenge); > byte[] signedData = rawMessageCodec.encodeRegistrationSignedBytes(applicationSha256, challengeSha256, keyHandle, userPublicKey); > byte[] signature = keyPairGenerator.sign(signedData, certificatePrivateKey); > return new EnrollmentResponse(userPublicKey, keyHandle, vendorCertificate, signature); Now, all the data is converted into one-byte array, then one additional parameter is added, determining if the request is approved or denied, as follows: > JSONObject clientData = new JSONObject(); > if (isDeny){ > clientData.put(JSON_PROPERTY_REQUEST_TYPE, REGISTER_CANCEL_TYPE);//Deny > } else { > clientData.put(JSON_PROPERTY_REQUEST_TYPE, REQUEST_TYPE_REGISTER);//Approve > } > clientData.put(JSON_PROPERTY_SERVER_CHALLENGE, challenge); > clientData.put(JSON_PROPERTY_SERVER_ORIGIN, origin); > > String clientDataString = clientData.toString(); > byte[] resp = rawMessageCodec.encodeRegisterResponse(enrollmentResponse); > > JSONObject response = new JSONObject(); > response.put(\"registrationData\", Utils.base64UrlEncode(resp)); > response.put(\"clientData\", Utils.base64UrlEncode(clientDataString.getBytes(Charset.forName(\"ASCII\")))); > response.put(\"deviceData\", Utils.base64UrlEncode(deviceDataString.getBytes(Charset.forName(\"ASCII\")))); > > TokenResponse tokenResponse = new TokenResponse(); > tokenResponse.setResponse(response.toString()); > tokenResponse.setChallenge(new String(challenge)); > tokenResponse.setKeyHandle(new String(enrollmentResponse.getKeyHandle())); > > return tokenResponse; For authentication, all information is associated with your device UDID and the app retrieves the data from the data store each time, as follows: > TokenEntry tokenEntry = dataStore.getTokenEntry(keyHandle); > String keyPairJson = tokenEntry.getKeyPair(); > keyPair = keyPairGenerator.keyPairFromJson(keyPairJson); > int counter = dataStore.incrementCounter(keyHandle); > byte userPresence = userPresenceVerifier.verifyUserPresence(); > byte[] applicationSha256 = DigestUtils.sha256(application); > byte[] challengeSha256 = DigestUtils.sha256(challenge); > byte[] signedData = rawMessageCodec.encodeAuthenticateSignedBytes(applicationSha256, userPresence, counter, challengeSha256); > return new AuthenticateResponse(userPresence, counter, signature); The onEnroll and onSign methods prepare the parameters and data before the call to the server. For more information about these two methods, see the Super Gluu Git repo. Now, the app makes one last call to the server: > final Map parameters = new HashMap(); > parameters.put(\"username\", oxPush2Request.getUserName()); > parameters.put(\"tokenResponse\", tokenResponse.getResponse()); > > final String resultJsonResponse = CommunicationService.post(u2fEndpoint, parameters); The string resultJsonResponse contains the JSON result. The app extracts some additional information from this result. Check enrollment or authentication success using the u2fOperationResult.getStatus() field, as follows: > LogInfo log = new LogInfo(); > log.setIssuer(oxPush2Request.getIssuer()); > log.setUserName(oxPush2Request.getUserName()); > log.setLocationIP(oxPush2Request.getLocationIP()); > log.setLocationAddress(oxPush2Request.getLocationCity()); > log.setCreatedDate(String.valueOf(System.currentTimeMillis()));//oxPush2Request.getCreated()); > log.setMethod(oxPush2Request.getMethod()); Testing locally # The following is a method for testing Super Gluu locally on a non-public server. This guide assumes a Gluu Server has been installed and is operational. Warning The following testing steps mimic a MITM attack, so needless to say, these instructions are for development purposes only! In the Gluu Server VM settings, change the network adapter connection type from NAT to Bridged; The Gluu Server and smartphone should be connected to WiFi on the same local network Log into the VM and run ifconfig in the terminal to get the IP address of the Gluu Server In oxTrust, enable the Super Gluu authentication script Update the host file on the machine where you are running the browser to log in. Example: 192.168.1.232 c67.example.info Run ipconfig / ifconfig on the machine where you are planning to run your DNS server. Configure any DNS server to allow resovle u144.example.info.=192.168.1.232 . For example you can use a lightweight WindowsDNS DNS proxy server Create a dns.config file in the folder with dedserver.jar. Example file content: u144.example.info.=192.168.1.232 Checkut and build https://github.com/JonahAragon/WindowsDNS Run the DNS server using a command like this: java -jar dedserver.jar Create a dns.config file in the folder with dedserver.jar . Example file content: u144.example.info.=192.168.1.232 Run the DNS server using a command like this: java -jar dedserver.jar On your mobile phone, open the WiFi connection details and specify the DNS server IP from Step 6 Now you can test Super Gluu After you finish testing, don't forget to change your WiFi connection type on the mobile phone back to use the automatic settings.","title":"Developer Guide"},{"location":"supergluu/developer-guide/#super-gluu-developer-guide","text":"Super Gluu is a two-factor authentication mobile application for iOS and Android. Super Gluu can be used as a strong authentication mechanism to access resources that are protected by Gluu's free open source central authentication server, called the Gluu Server . The below documentation describes what is happening during user enrollment and authentication.","title":"Super Gluu Developer Guide"},{"location":"supergluu/developer-guide/#qr-code","text":"During enrollment and authentication, the app goes through a few steps: The user scans the QR code, which contains identification data in the following format: { \"app\" : \"https://example.gluu.org\", \"state\" : \"dek4nwk6-dk56-sr43-4frt-4jfi30fltimd\" \"issuer\" : \"https://example.gluu.org\" \"created\" : \"2016-06-12T12:00:01.874000\" } Data from the QR code is changed into Fido U2F metadata: String discoveryUrl = oxPush2Request.getIssuer(); discoveryUrl += \"/.well-known/fido-u2f-configuration\"; final String discoveryJson = CommunicationService.get(discoveryUrl, null); final U2fMetaData u2fMetaData = new Gson().fromJson(discoveryJson, U2fMetaData.class); This metadata is sent to the server: ``` final List keyHandles = dataStore.getKeyHandlesByIssuerAndAppId(oxPush2Request.getIssuer(), oxPush2Request.getApp()); final boolean isEnroll = (keyHandles.size() == 0) || StringUtils.equals(oxPush2Request.getMethod(), \"enroll\"); final String u2fEndpoint; if (isEnroll) u2fEndpoint = u2fMetaData.getRegistrationEndpoint();// if enroll then get registration endpoint } else { u2fEndpoint = u2fMetaData.getAuthenticationEndpoint();// if authentication then get corresponding endpoint } validChallengeJsonResponse = CommunicationService.get(u2fEndpoint, parameters); ``` When the result comes back, it decides whether to enroll a new device or authenticate an existing one: if (isEnroll) { tokenResponse = oxPush2RequestListener.onEnroll(challengeJson, oxPush2Request, isDeny); } else { tokenResponse = oxPush2RequestListener.onSign(challengeJson, u2fMetaData.getIssuer(), isDeny); }","title":"QR Code"},{"location":"supergluu/developer-guide/#enrollment-process","text":"If you scan a QR code for the first time and your device's UDID isn't attached to your user ID, the app will enroll it. First, it needs to prepare the data properties, as follows: > String version = request.getString(JSON_PROPERTY_VERSION); > String appParam = request.getString(JSON_PROPERTY_APP_ID); > String challenge = request.getString(JSON_PROPERTY_SERVER_CHALLENGE); > String origin = oxPush2Request.getIssuer(); > > EnrollmentResponse enrollmentResponse = u2fKey.register(new EnrollmentRequest(version, appParam, challenge, oxPush2Request)); During registration, the app generates a unique keyHandle and keyPair (public/private keys) to sign all data and uses an ECC algorithm to encode the required data, as follows: > TokenEntry tokenEntry = new TokenEntry(keyPairGenerator.keyPairToJson(keyPair), enrollmentRequest.getApplication(), enrollmentRequest.getOxPush2Request().getIssuer()); > . > . > . > dataStore.storeTokenEntry(keyHandle, tokenEntry); > byte[] userPublicKey = keyPairGenerator.encodePublicKey(keyPair.getPublic()); > > byte[] applicationSha256 = DigestUtils.sha256(application); > byte[] challengeSha256 = DigestUtils.sha256(challenge); > byte[] signedData = rawMessageCodec.encodeRegistrationSignedBytes(applicationSha256, challengeSha256, keyHandle, userPublicKey); > byte[] signature = keyPairGenerator.sign(signedData, certificatePrivateKey); > return new EnrollmentResponse(userPublicKey, keyHandle, vendorCertificate, signature); Now, all the data is converted into one-byte array, then one additional parameter is added, determining if the request is approved or denied, as follows: > JSONObject clientData = new JSONObject(); > if (isDeny){ > clientData.put(JSON_PROPERTY_REQUEST_TYPE, REGISTER_CANCEL_TYPE);//Deny > } else { > clientData.put(JSON_PROPERTY_REQUEST_TYPE, REQUEST_TYPE_REGISTER);//Approve > } > clientData.put(JSON_PROPERTY_SERVER_CHALLENGE, challenge); > clientData.put(JSON_PROPERTY_SERVER_ORIGIN, origin); > > String clientDataString = clientData.toString(); > byte[] resp = rawMessageCodec.encodeRegisterResponse(enrollmentResponse); > > JSONObject response = new JSONObject(); > response.put(\"registrationData\", Utils.base64UrlEncode(resp)); > response.put(\"clientData\", Utils.base64UrlEncode(clientDataString.getBytes(Charset.forName(\"ASCII\")))); > response.put(\"deviceData\", Utils.base64UrlEncode(deviceDataString.getBytes(Charset.forName(\"ASCII\")))); > > TokenResponse tokenResponse = new TokenResponse(); > tokenResponse.setResponse(response.toString()); > tokenResponse.setChallenge(new String(challenge)); > tokenResponse.setKeyHandle(new String(enrollmentResponse.getKeyHandle())); > > return tokenResponse; For authentication, all information is associated with your device UDID and the app retrieves the data from the data store each time, as follows: > TokenEntry tokenEntry = dataStore.getTokenEntry(keyHandle); > String keyPairJson = tokenEntry.getKeyPair(); > keyPair = keyPairGenerator.keyPairFromJson(keyPairJson); > int counter = dataStore.incrementCounter(keyHandle); > byte userPresence = userPresenceVerifier.verifyUserPresence(); > byte[] applicationSha256 = DigestUtils.sha256(application); > byte[] challengeSha256 = DigestUtils.sha256(challenge); > byte[] signedData = rawMessageCodec.encodeAuthenticateSignedBytes(applicationSha256, userPresence, counter, challengeSha256); > return new AuthenticateResponse(userPresence, counter, signature); The onEnroll and onSign methods prepare the parameters and data before the call to the server. For more information about these two methods, see the Super Gluu Git repo. Now, the app makes one last call to the server: > final Map parameters = new HashMap(); > parameters.put(\"username\", oxPush2Request.getUserName()); > parameters.put(\"tokenResponse\", tokenResponse.getResponse()); > > final String resultJsonResponse = CommunicationService.post(u2fEndpoint, parameters); The string resultJsonResponse contains the JSON result. The app extracts some additional information from this result. Check enrollment or authentication success using the u2fOperationResult.getStatus() field, as follows: > LogInfo log = new LogInfo(); > log.setIssuer(oxPush2Request.getIssuer()); > log.setUserName(oxPush2Request.getUserName()); > log.setLocationIP(oxPush2Request.getLocationIP()); > log.setLocationAddress(oxPush2Request.getLocationCity()); > log.setCreatedDate(String.valueOf(System.currentTimeMillis()));//oxPush2Request.getCreated()); > log.setMethod(oxPush2Request.getMethod());","title":"Enrollment Process"},{"location":"supergluu/developer-guide/#testing-locally","text":"The following is a method for testing Super Gluu locally on a non-public server. This guide assumes a Gluu Server has been installed and is operational. Warning The following testing steps mimic a MITM attack, so needless to say, these instructions are for development purposes only! In the Gluu Server VM settings, change the network adapter connection type from NAT to Bridged; The Gluu Server and smartphone should be connected to WiFi on the same local network Log into the VM and run ifconfig in the terminal to get the IP address of the Gluu Server In oxTrust, enable the Super Gluu authentication script Update the host file on the machine where you are running the browser to log in. Example: 192.168.1.232 c67.example.info Run ipconfig / ifconfig on the machine where you are planning to run your DNS server. Configure any DNS server to allow resovle u144.example.info.=192.168.1.232 . For example you can use a lightweight WindowsDNS DNS proxy server Create a dns.config file in the folder with dedserver.jar. Example file content: u144.example.info.=192.168.1.232 Checkut and build https://github.com/JonahAragon/WindowsDNS Run the DNS server using a command like this: java -jar dedserver.jar Create a dns.config file in the folder with dedserver.jar . Example file content: u144.example.info.=192.168.1.232 Run the DNS server using a command like this: java -jar dedserver.jar On your mobile phone, open the WiFi connection details and specify the DNS server IP from Step 6 Now you can test Super Gluu After you finish testing, don't forget to change your WiFi connection type on the mobile phone back to use the automatic settings.","title":"Testing locally"},{"location":"supergluu/user-guide/","tags":["Super Gluu","User Guide"],"text":"Super Gluu User Guide # This guide will show how to use the Super Gluu two-factor authentication mobile application. It covers the initial setup, managing keys and logs, and general settings. Note The screenshots below are shown in iOS. Android is roughly the same. Initial Setup # Camera Access Prompt # After installation, Super Gluu will request access to use your camera, which is used to scan a QR code to set up your two-factor authentication. Choose Login Method # For additional security, Super Gluu gives you the option to configure either a passcode or TouchID to access Super Gluu. This choice can be changed in the application settings later. Note After 5 unsuccessful attempts to enter the passcode, the app is locked for 10 minutes. Screen for the passcode and TouchID selection Screen for enabling passcode Screen for enabling TouchID Confirm Push Notification # Next, it will ask for permission to send push notifications from the Flex. This choice can be changed later in the device settings. More information about the push notification will be covered later in the document. Main Screen # After configuration, the main screen is displayed. It features the main enrollment button in the center and the menu button in the top right. QR Code Enrollment # To enroll a device, enter the credentials in your Flex web app to generate a QR code, then click the Scan QR Code button on the Super Gluu app's Home screen: After it scans the code and the server returns the request correctly, it will prompt to Approve or Deny . To continue the enrollment/authentication process, click Approve : The timer on the top right of the screen shows the time limit to choose to Approve or Deny . As time runs out, the number's color will change: yellow if it's under 20 seconds, red if it's under 10. Next, it will redirect to the main page and display a success message. Menu # After pressing the menu button, you'll get the option to view logs, keys, settings, and help files. You can also check the current app version in the bottom right corner. Tapping it for several seconds will show the details of the latest commit. Logs # Each time it enrolls or authenticates a device, the app will save corresponding logs in the Logs tab. The log details whether authentication was successful, with more details available if the log is tapped on. Clear these logs if desired by swiping left on the log, then tapping the red button. The Log tab will report the enrollment and authentication process and display who logged in, when, and from where. Just tap on the log to get to the information screen. The information screen contains data about: Flex name & server URL Username IP address & location Time & date Keys # This tab contains all available keys for each Flex. A key is a unique file that is generated during enrollment and is used to authenticate the device on the server. If a key for a server is deleted, enroll again with a new key. Note If you delete a key from your app but wish to re-enroll the same device against the same server, the corresponding entry for that device also needs to be removed from the user record in the Flex. To change a key's name, swipe left on it and tap the green button. To delete a key, swipe left on the key, then tap the red button. Settings # In the Settings tab, there are options to configure the passcode or TouchID. Push Notifications # Super Gluu can receive push notifications from Flex. The server can send an enrollment or authentication request to the application, as if it scanned the QR code directly. After choosing to receive push notifications either during initial setup or through the Settings tab later, enroll through the server. Super Gluu will send a token to the server, which will be used to send push notifications to the device. After receiving the notification, tap Approve or Deny directly from the push menu. Super Gluu can receive a notification when the application is running in the foreground. It will look just like the original authentication screen. Device Settings, iPad Support # There are a few options for Super Gluu in the device settings - push notifications, location, access to the camera, and passcode protection. Any change made in the device settings will take effect in the application. Super Gluu can run on iPads, and the layout is the same for all IOS devices. For more information, please see the Gluu Website","title":"User Guide"},{"location":"supergluu/user-guide/#super-gluu-user-guide","text":"This guide will show how to use the Super Gluu two-factor authentication mobile application. It covers the initial setup, managing keys and logs, and general settings. Note The screenshots below are shown in iOS. Android is roughly the same.","title":"Super Gluu User Guide"},{"location":"supergluu/user-guide/#initial-setup","text":"","title":"Initial Setup"},{"location":"supergluu/user-guide/#camera-access-prompt","text":"After installation, Super Gluu will request access to use your camera, which is used to scan a QR code to set up your two-factor authentication.","title":"Camera Access Prompt"},{"location":"supergluu/user-guide/#choose-login-method","text":"For additional security, Super Gluu gives you the option to configure either a passcode or TouchID to access Super Gluu. This choice can be changed in the application settings later. Note After 5 unsuccessful attempts to enter the passcode, the app is locked for 10 minutes. Screen for the passcode and TouchID selection Screen for enabling passcode Screen for enabling TouchID","title":"Choose Login Method"},{"location":"supergluu/user-guide/#confirm-push-notification","text":"Next, it will ask for permission to send push notifications from the Flex. This choice can be changed later in the device settings. More information about the push notification will be covered later in the document.","title":"Confirm Push Notification"},{"location":"supergluu/user-guide/#main-screen","text":"After configuration, the main screen is displayed. It features the main enrollment button in the center and the menu button in the top right.","title":"Main Screen"},{"location":"supergluu/user-guide/#qr-code-enrollment","text":"To enroll a device, enter the credentials in your Flex web app to generate a QR code, then click the Scan QR Code button on the Super Gluu app's Home screen: After it scans the code and the server returns the request correctly, it will prompt to Approve or Deny . To continue the enrollment/authentication process, click Approve : The timer on the top right of the screen shows the time limit to choose to Approve or Deny . As time runs out, the number's color will change: yellow if it's under 20 seconds, red if it's under 10. Next, it will redirect to the main page and display a success message.","title":"QR Code Enrollment"},{"location":"supergluu/user-guide/#menu","text":"After pressing the menu button, you'll get the option to view logs, keys, settings, and help files. You can also check the current app version in the bottom right corner. Tapping it for several seconds will show the details of the latest commit.","title":"Menu"},{"location":"supergluu/user-guide/#logs","text":"Each time it enrolls or authenticates a device, the app will save corresponding logs in the Logs tab. The log details whether authentication was successful, with more details available if the log is tapped on. Clear these logs if desired by swiping left on the log, then tapping the red button. The Log tab will report the enrollment and authentication process and display who logged in, when, and from where. Just tap on the log to get to the information screen. The information screen contains data about: Flex name & server URL Username IP address & location Time & date","title":"Logs"},{"location":"supergluu/user-guide/#keys","text":"This tab contains all available keys for each Flex. A key is a unique file that is generated during enrollment and is used to authenticate the device on the server. If a key for a server is deleted, enroll again with a new key. Note If you delete a key from your app but wish to re-enroll the same device against the same server, the corresponding entry for that device also needs to be removed from the user record in the Flex. To change a key's name, swipe left on it and tap the green button. To delete a key, swipe left on the key, then tap the red button.","title":"Keys"},{"location":"supergluu/user-guide/#settings","text":"In the Settings tab, there are options to configure the passcode or TouchID.","title":"Settings"},{"location":"supergluu/user-guide/#push-notifications","text":"Super Gluu can receive push notifications from Flex. The server can send an enrollment or authentication request to the application, as if it scanned the QR code directly. After choosing to receive push notifications either during initial setup or through the Settings tab later, enroll through the server. Super Gluu will send a token to the server, which will be used to send push notifications to the device. After receiving the notification, tap Approve or Deny directly from the push menu. Super Gluu can receive a notification when the application is running in the foreground. It will look just like the original authentication screen.","title":"Push Notifications"},{"location":"supergluu/user-guide/#device-settings-ipad-support","text":"There are a few options for Super Gluu in the device settings - push notifications, location, access to the camera, and passcode protection. Any change made in the device settings will take effect in the application. Super Gluu can run on iPads, and the layout is the same for all IOS devices. For more information, please see the Gluu Website","title":"Device Settings, iPad Support"}]} \ No newline at end of file