Register rapp-qonto KeyCape client
This commit is contained in:
parent
9026d7f904
commit
11a14648c4
3 changed files with 44 additions and 18 deletions
|
|
@ -131,6 +131,15 @@ clients:
|
|||
allowedScopes: ["openid", "profile", "email", "groups"]
|
||||
grantTypes: ["authorization_code"]
|
||||
clientType: "public"
|
||||
- clientId: "rapp-qonto-client"
|
||||
displayName: "rapp-qonto workload"
|
||||
allowedScopes: ["qonto:read"]
|
||||
grantTypes: ["client_credentials"]
|
||||
clientType: "confidential"
|
||||
secretRef: "env:KEYCAPE_RAPP_QONTO_CLIENT_SECRET"
|
||||
serviceSubject: "rapp-qonto"
|
||||
tenant: "tenant:friendly:binky"
|
||||
roles: ["qonto-reader"]
|
||||
EOF
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ spec:
|
|||
# 2026-05-24: direct-imported into railiance01 k3s for the
|
||||
# bootstrap-console OIDC/MFA rollout. Use IfNotPresent while the
|
||||
# HTTP registry push/pull path is being cleaned up.
|
||||
image: 92.205.130.254:32166/coulomb/key-cape:main-nonce-0601
|
||||
image: 92.205.130.254:32166/coulomb/key-cape:main-e877d27-2
|
||||
imagePullPolicy: IfNotPresent
|
||||
|
||||
ports:
|
||||
|
|
@ -65,6 +65,11 @@ spec:
|
|||
env:
|
||||
- name: KEYCAPE_CONFIG
|
||||
value: /etc/keycape/config.yaml
|
||||
- name: KEYCAPE_RAPP_QONTO_CLIENT_SECRET
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: keycape-rapp-qonto-client
|
||||
key: client-secret
|
||||
|
||||
volumeMounts:
|
||||
# keycape-config Secret provides config.yaml and key.pem
|
||||
|
|
|
|||
|
|
@ -34,6 +34,18 @@ OPENBAO_CLIENT = {
|
|||
"clientType": "public",
|
||||
}
|
||||
|
||||
RAPP_QONTO_CLIENT = {
|
||||
"clientId": "rapp-qonto-client",
|
||||
"displayName": "rapp-qonto workload",
|
||||
"allowedScopes": ["qonto:read"],
|
||||
"grantTypes": ["client_credentials"],
|
||||
"clientType": "confidential",
|
||||
"secretRef": "env:KEYCAPE_RAPP_QONTO_CLIENT_SECRET",
|
||||
"serviceSubject": "rapp-qonto",
|
||||
"tenant": "tenant:friendly:binky",
|
||||
"roles": ["qonto-reader"],
|
||||
}
|
||||
|
||||
LLDAP_REQUIRED = {
|
||||
"userOU": "ou=people",
|
||||
"groupOU": "ou=groups",
|
||||
|
|
@ -55,38 +67,38 @@ def load_config() -> dict[str, Any]:
|
|||
return config
|
||||
|
||||
|
||||
def client_errors(config: dict[str, Any]) -> list[str]:
|
||||
def client_errors(config: dict[str, Any], required: dict[str, Any]) -> list[str]:
|
||||
clients = config.get("clients")
|
||||
if not isinstance(clients, list):
|
||||
return ["clients must be a list"]
|
||||
target = next(
|
||||
(client for client in clients if isinstance(client, dict) and client.get("clientId") == OPENBAO_CLIENT["clientId"]),
|
||||
(client for client in clients if isinstance(client, dict) and client.get("clientId") == required["clientId"]),
|
||||
None,
|
||||
)
|
||||
if target is None:
|
||||
return ["missing openbao-admin client"]
|
||||
return [f"missing {required['clientId']} client"]
|
||||
|
||||
errors: list[str] = []
|
||||
for key in ("displayName", "clientType"):
|
||||
if target.get(key) != OPENBAO_CLIENT[key]:
|
||||
errors.append(f"{key} should be {OPENBAO_CLIENT[key]!r}")
|
||||
for key in ("redirectUris", "allowedScopes", "grantTypes"):
|
||||
missing = sorted(set(OPENBAO_CLIENT[key]) - set(target.get(key) or []))
|
||||
if missing:
|
||||
errors.append(f"{key} missing: {', '.join(missing)}")
|
||||
for key, expected in required.items():
|
||||
if key in ("redirectUris", "allowedScopes", "grantTypes", "roles"):
|
||||
missing = sorted(set(expected) - set(target.get(key) or []))
|
||||
if missing:
|
||||
errors.append(f"{required['clientId']}.{key} missing: {', '.join(missing)}")
|
||||
elif target.get(key) != expected:
|
||||
errors.append(f"{required['clientId']}.{key} should be {expected!r}")
|
||||
return errors
|
||||
|
||||
|
||||
def upsert_client(config: dict[str, Any]) -> dict[str, Any]:
|
||||
def upsert_client(config: dict[str, Any], required: dict[str, Any]) -> dict[str, Any]:
|
||||
clients = config.get("clients")
|
||||
if not isinstance(clients, list):
|
||||
clients = []
|
||||
config["clients"] = clients
|
||||
for index, client in enumerate(clients):
|
||||
if isinstance(client, dict) and client.get("clientId") == OPENBAO_CLIENT["clientId"]:
|
||||
clients[index] = dict(OPENBAO_CLIENT)
|
||||
if isinstance(client, dict) and client.get("clientId") == required["clientId"]:
|
||||
clients[index] = dict(required)
|
||||
return config
|
||||
clients.append(dict(OPENBAO_CLIENT))
|
||||
clients.append(dict(required))
|
||||
return config
|
||||
|
||||
|
||||
|
|
@ -111,7 +123,7 @@ def enforce_lldap_defaults(config: dict[str, Any]) -> dict[str, Any]:
|
|||
|
||||
|
||||
def render_patch(config: dict[str, Any]) -> None:
|
||||
updated = enforce_lldap_defaults(upsert_client(config))
|
||||
updated = enforce_lldap_defaults(upsert_client(upsert_client(config, OPENBAO_CLIENT), RAPP_QONTO_CLIENT))
|
||||
config_text = yaml.safe_dump(updated, sort_keys=False)
|
||||
encoded = base64.b64encode(config_text.encode("utf-8")).decode("ascii")
|
||||
json.dump({"data": {"config.yaml": encoded}}, sys.stdout, separators=(",", ":"))
|
||||
|
|
@ -119,12 +131,12 @@ def render_patch(config: dict[str, Any]) -> None:
|
|||
|
||||
|
||||
def verify(config: dict[str, Any]) -> None:
|
||||
errors = client_errors(config) + lldap_errors(config)
|
||||
errors = client_errors(config, OPENBAO_CLIENT) + client_errors(config, RAPP_QONTO_CLIENT) + lldap_errors(config)
|
||||
if errors:
|
||||
for error in errors:
|
||||
print(f"[FAIL] {error}")
|
||||
raise SystemExit(1)
|
||||
print("[PASS] openbao-admin client and LLDAP OU lookup settings are present")
|
||||
print("[PASS] openbao-admin and rapp-qonto clients and LLDAP OU lookup settings are present")
|
||||
|
||||
|
||||
def main() -> None:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue