-
Notifications
You must be signed in to change notification settings - Fork 38
feat: use Client Credentials for managing Keycloak Clients #1341
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
32 commits
Select commit
Hold shift + click to select a range
4a67238
Client Credentials mode for managing Keycloak Clients
slaskawi db0d603
Client Credentials grant documentation
slaskawi 4dd4ded
Moved docs to the other PR
slaskawi 0d5507f
Keycloak Client mode
slaskawi d260670
Doc updates
slaskawi 0ad7c9f
Update docs/reference/configuration/Single Sign-On/overview.md
slaskawi 77dbf38
Merge remote-tracking branch 'origin/main' into pepr_keycloak_client_…
slaskawi 55fe732
Merge remote-tracking branch 'origin/pepr_keycloak_client_management-…
slaskawi aa02ae2
More functional approach
slaskawi 97837f7
More refactoring
slaskawi 4c1135e
Lint
slaskawi 7127188
Lint
slaskawi b98e0ff
Update src/pepr/operator/README.md
slaskawi f414764
Merge remote-tracking branch 'origin/main' into pepr_keycloak_client_…
slaskawi 550131a
Comments addressed
slaskawi 6a9e87a
Merge remote-tracking branch 'origin/pepr_keycloak_client_management'…
slaskawi 7b97457
Fixed bootstrap error
slaskawi 3befcf7
Tidy up
slaskawi e727907
Merge remote-tracking branch 'origin/main' into pepr_keycloak_client_…
slaskawi 87be45e
Comments addressed
slaskawi 9b9e783
lint
slaskawi 222aa83
More backwards compatibility and migration code
slaskawi 64dadea
Update src/pepr/operator/controllers/keycloak/clients/dynamic-client-…
slaskawi b9cc8e5
Update src/pepr/operator/controllers/keycloak/clients/keycloak-client.ts
slaskawi 110d1d9
Update src/pepr/operator/controllers/keycloak/clients/keycloak-client.ts
slaskawi f4d21ff
Update src/pepr/operator/controllers/keycloak/clients/keycloak-client.ts
slaskawi 446b831
Comments addressed
slaskawi 926619d
Update src/pepr/operator/controllers/keycloak/config.ts
slaskawi ecc76de
Update src/pepr/operator/controllers/keycloak/clients/client-credenti…
slaskawi 4034904
lint
slaskawi 66a8743
Merge branch 'main' into pepr_keycloak_client_management
slaskawi 33fc7ae
Update src/pepr/operator/controllers/keycloak/clients/client-credenti…
mjnagel File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
2 changes: 1 addition & 1 deletion
2
docs/.images/diagrams/uds-core-operator-authservice-keycloak.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
117 changes: 69 additions & 48 deletions
117
docs/.images/diagrams/uds-core-pepr-operator-flow.drawio
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
61 changes: 61 additions & 0 deletions
61
src/pepr/operator/controllers/keycloak/client-secret-sync.spec.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,61 @@ | ||
| /** | ||
| * Copyright 2025 Defense Unicorns | ||
| * SPDX-License-Identifier: AGPL-3.0-or-later OR LicenseRef-Defense-Unicorns-Commercial | ||
| */ | ||
|
|
||
| import { describe, expect, it } from "@jest/globals"; | ||
| import { | ||
| updateKeycloakClientsSecret, | ||
| KEYCLOAK_CLIENT_SECRET_KEY, | ||
| KEYCLOAK_CLIENTS_SECRET_NAME, | ||
| KEYCLOAK_CLIENTS_SECRET_NAMESPACE, | ||
| } from "./client-secret-sync"; | ||
|
|
||
| interface Config { | ||
| metadata: { | ||
| name: string; | ||
| namespace: string; | ||
| }; | ||
| data: { | ||
| [key: string]: string; | ||
| }; | ||
| } | ||
|
|
||
| const createConfig = (data: { [key: string]: string } = {}): Config => ({ | ||
| metadata: { | ||
| name: KEYCLOAK_CLIENTS_SECRET_NAME, | ||
| namespace: KEYCLOAK_CLIENTS_SECRET_NAMESPACE, | ||
| }, | ||
| data, | ||
| }); | ||
|
|
||
| describe("updateKeycloakClientsSecret Tests", () => { | ||
| it("should generate a new secret if KEYCLOAK_CLIENT_SECRET_KEY does not exist", async () => { | ||
| const config = createConfig(); | ||
|
|
||
| await updateKeycloakClientsSecret(config); | ||
|
|
||
| expect(config.data[KEYCLOAK_CLIENT_SECRET_KEY]).not.toBe(""); | ||
| }); | ||
|
|
||
| it("should generate a new secret if forceRotation is true", async () => { | ||
| const config = createConfig({ | ||
| [KEYCLOAK_CLIENT_SECRET_KEY]: "existing-secret", | ||
| }); | ||
|
|
||
| await updateKeycloakClientsSecret(config, true); | ||
|
|
||
| expect(config.data[KEYCLOAK_CLIENT_SECRET_KEY]).not.toBe(""); | ||
| expect(config.data[KEYCLOAK_CLIENT_SECRET_KEY]).not.toBe("existing-secret"); | ||
| }); | ||
|
|
||
| it("should not generate a new secret if KEYCLOAK_CLIENT_SECRET_KEY exists and forceRotation is false", async () => { | ||
| const config = createConfig({ | ||
| [KEYCLOAK_CLIENT_SECRET_KEY]: "existing-secret", | ||
| }); | ||
|
|
||
| await updateKeycloakClientsSecret(config); | ||
|
|
||
| expect(config.data[KEYCLOAK_CLIENT_SECRET_KEY]).toBe("existing-secret"); | ||
| }); | ||
| }); |
39 changes: 39 additions & 0 deletions
39
src/pepr/operator/controllers/keycloak/client-secret-sync.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| /** | ||
| * Copyright 2025 Defense Unicorns | ||
| * SPDX-License-Identifier: AGPL-3.0-or-later OR LicenseRef-Defense-Unicorns-Commercial | ||
| */ | ||
|
|
||
| import { K8s, kind } from "pepr"; | ||
| import { v4 as uuidv4 } from "uuid"; | ||
| import { Component, setupLogger } from "../../../logger"; | ||
|
|
||
| export const KEYCLOAK_CLIENT_SECRET_KEY = "uds-operator"; | ||
|
|
||
| export const KEYCLOAK_CLIENTS_SECRET_NAMESPACE = "keycloak"; | ||
| export const KEYCLOAK_CLIENTS_SECRET_NAME = "keycloak-client-secrets"; | ||
|
|
||
| const log = setupLogger(Component.OPERATOR_CONFIG); | ||
|
|
||
| /** | ||
| * Updates the Keycloak client secret in the provided config. | ||
| * If the secret does not exist or forceRotation is true, a new secret is generated. | ||
| * The secret is then applied to the Kubernetes cluster. | ||
| * | ||
| * @param {kind.Secret} config - The Kubernetes Secret object to update. | ||
| * @param {boolean} [forceRotation=false] - Whether to force rotation of the secret. | ||
| */ | ||
| export async function updateKeycloakClientsSecret( | ||
| config: kind.Secret, | ||
| forceRotation: boolean = false, | ||
| ) { | ||
| config.data = config.data || {}; | ||
|
|
||
| // This might be a bug but it seems Zarf adds managedFields, which is prohibited in Secrets. | ||
| delete config.metadata?.managedFields; | ||
|
mjnagel marked this conversation as resolved.
|
||
|
|
||
| if (!config.data[KEYCLOAK_CLIENT_SECRET_KEY] || forceRotation) { | ||
| log.info("Generating new Keycloak client secret"); | ||
| config.data[KEYCLOAK_CLIENT_SECRET_KEY] = Buffer.from(uuidv4()).toString("base64"); | ||
| await K8s(kind.Secret).Apply(config); | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.