Add KeyCape client registration for coulomb.social
Idempotent patch of sso/keycape-config with public PKCE client and redirect URIs for local :8008 and production coulomb.social callbacks.
This commit is contained in:
parent
62b1ea3d59
commit
27656916db
2 changed files with 84 additions and 0 deletions
64
sso-mfa/k8s/keycape/register-coulomb-social.py
Executable file
64
sso-mfa/k8s/keycape/register-coulomb-social.py
Executable file
|
|
@ -0,0 +1,64 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Idempotently register coulomb.social in the live KeyCape Secret.
|
||||||
|
|
||||||
|
The complete Secret travels over stdin/stdout between kubectl and this
|
||||||
|
process. Secret values are never printed to the terminal or written to disk.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import base64
|
||||||
|
import json
|
||||||
|
import sys
|
||||||
|
|
||||||
|
import yaml
|
||||||
|
|
||||||
|
CLIENT_ID = "coulomb-social"
|
||||||
|
CLIENT = {
|
||||||
|
"clientId": CLIENT_ID,
|
||||||
|
"displayName": "coulomb.social",
|
||||||
|
"redirectUris": [
|
||||||
|
"http://127.0.0.1:8008/auth/callback/",
|
||||||
|
"http://localhost:8008/auth/callback/",
|
||||||
|
# Production host (register only when TLS + app deploy ready)
|
||||||
|
"https://coulomb.social/auth/callback/",
|
||||||
|
],
|
||||||
|
"allowedScopes": ["openid", "profile", "email", "groups"],
|
||||||
|
"grantTypes": ["authorization_code"],
|
||||||
|
"clientType": "public",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def main() -> None:
|
||||||
|
secret = json.load(sys.stdin)
|
||||||
|
encoded = secret.get("data", {}).get("config.yaml")
|
||||||
|
if not encoded:
|
||||||
|
raise SystemExit("keycape-config does not contain config.yaml")
|
||||||
|
config = yaml.safe_load(base64.b64decode(encoded))
|
||||||
|
clients = config.setdefault("clients", [])
|
||||||
|
existing = next(
|
||||||
|
(
|
||||||
|
index
|
||||||
|
for index, client in enumerate(clients)
|
||||||
|
if client.get("clientId") == CLIENT_ID
|
||||||
|
),
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
if existing is None:
|
||||||
|
clients.append(CLIENT)
|
||||||
|
else:
|
||||||
|
# Preserve any extra fields operators may have set; overwrite known keys.
|
||||||
|
merged = dict(clients[existing])
|
||||||
|
merged.update(CLIENT)
|
||||||
|
clients[existing] = merged
|
||||||
|
rendered = yaml.safe_dump(config, sort_keys=False).encode()
|
||||||
|
secret["data"]["config.yaml"] = base64.b64encode(rendered).decode()
|
||||||
|
secret.pop("status", None)
|
||||||
|
metadata = secret.get("metadata", {})
|
||||||
|
for key in ("creationTimestamp", "managedFields", "resourceVersion", "uid"):
|
||||||
|
metadata.pop(key, None)
|
||||||
|
json.dump(secret, sys.stdout, separators=(",", ":"))
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
20
sso-mfa/k8s/keycape/register-coulomb-social.sh
Executable file
20
sso-mfa/k8s/keycape/register-coulomb-social.sh
Executable file
|
|
@ -0,0 +1,20 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
# Register coulomb.social as a public KeyCape OIDC client (idempotent).
|
||||||
|
# Never prints Secret values.
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
NAMESPACE="${KEYCAPE_NAMESPACE:-sso}"
|
||||||
|
SECRET="${KEYCAPE_CONFIG_SECRET:-keycape-config}"
|
||||||
|
KUBECTL="${KUBECTL:-kubectl}"
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
|
||||||
|
"$KUBECTL" get secret "$SECRET" -n "$NAMESPACE" -o json \
|
||||||
|
| python3 "$SCRIPT_DIR/register-coulomb-social.py" \
|
||||||
|
| "$KUBECTL" apply -f -
|
||||||
|
|
||||||
|
echo "Registered coulomb-social client in $NAMESPACE/$SECRET"
|
||||||
|
|
||||||
|
# KeyCape loads config at process start.
|
||||||
|
"$KUBECTL" -n "$NAMESPACE" rollout restart deploy/keycape
|
||||||
|
"$KUBECTL" -n "$NAMESPACE" rollout status deploy/keycape --timeout=120s
|
||||||
|
echo "KeyCape rolled out."
|
||||||
Loading…
Add table
Add a link
Reference in a new issue