#!/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()