recipe-maintainer: public snapshot (secrets + deployment plans removed, single commit)
Sanitized single-commit public mirror of recipe-maintainer. - Removed test-ssh/.testenv (live creds); added test-ssh/.testenv.example placeholders. - Removed plans/ and planned-updates/ (deployment-planning docs) so no client/ deployment domains appear in the public repo. - All other secret stores were already gitignored. - docs.coopcloud.tech retained as a submodule (public upstream).
This commit is contained in:
133
recipe-info/authentik/setup_docs_integration.py
Normal file
133
recipe-info/authentik/setup_docs_integration.py
Normal file
@ -0,0 +1,133 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Setup Authentik OIDC integration for La Suite Docs (ld2).
|
||||
|
||||
Creates an OAuth2 provider, application, and test user in Authentik,
|
||||
then inserts the client secret and updates the Docs env file with
|
||||
Authentik OIDC endpoints.
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", ".."))
|
||||
|
||||
from lib.abra import app_secret_insert
|
||||
from lib.authentik import AuthentikAdmin
|
||||
from lib.env import apply_env_overrides, get_abra_env_path, read_env_file
|
||||
from lib.models import load_default_instance
|
||||
from lib.secrets import load_secrets
|
||||
|
||||
# Configuration
|
||||
PROVIDER_NAME = "lasuite-docs"
|
||||
APP_SLUG = "lasuite-docs"
|
||||
CLIENT_ID = "docs"
|
||||
TEST_USER = "testuser"
|
||||
TEST_PASS = "testpass123"
|
||||
TEST_EMAIL = f"{TEST_USER}@test.example.com"
|
||||
|
||||
def main():
|
||||
inst = load_default_instance()
|
||||
ak_domain = inst.default_domain("authentik")
|
||||
# Docs instance uses a custom domain (ld2) to avoid conflict with keycloak-backed docs
|
||||
DOCS_DOMAIN = f"ld2.{inst.domain_suffix}"
|
||||
ak_url = f"https://{ak_domain}"
|
||||
|
||||
# Get Authentik admin token from synced secrets
|
||||
ak_secrets = load_secrets(ak_domain)
|
||||
ak_token = ak_secrets["admin_token"]
|
||||
|
||||
ak = AuthentikAdmin(ak_url, ak_token)
|
||||
|
||||
# Resolve Authentik UUIDs
|
||||
uuids = ak.resolve_uuids()
|
||||
|
||||
# Step 1: Create OAuth2 provider
|
||||
provider_pk, client_secret = ak.ensure_provider(
|
||||
PROVIDER_NAME, CLIENT_ID,
|
||||
redirect_uris=[{
|
||||
"matching_mode": "strict",
|
||||
"url": f"https://{DOCS_DOMAIN}/api/v1.0/callback/",
|
||||
}],
|
||||
uuids=uuids,
|
||||
)
|
||||
|
||||
# Step 2: Create application
|
||||
ak.ensure_application("La Suite Docs", APP_SLUG, provider_pk,
|
||||
f"https://{DOCS_DOMAIN}")
|
||||
|
||||
# Step 3: Create test user
|
||||
user_pk = ak.ensure_user(TEST_USER, TEST_EMAIL, TEST_PASS)
|
||||
app_password = ak.ensure_app_password(user_pk)
|
||||
|
||||
# Step 4: Insert client secret into Docs via abra
|
||||
print("=== Insert OIDC client secret into Docs (ld2) ===", flush=True)
|
||||
env_path = get_abra_env_path(inst.server, DOCS_DOMAIN)
|
||||
if not env_path.exists():
|
||||
print(f" WARNING: Docs env file not found at {env_path}", flush=True)
|
||||
print(f" Create the app first: abra app new lasuite-docs --server {inst.server} --domain {DOCS_DOMAIN} --no-input", flush=True)
|
||||
print(" Skipping secret insertion and env update", flush=True)
|
||||
else:
|
||||
env_data = read_env_file(env_path)
|
||||
current_version = env_data.get("SECRET_OIDC_RPCS_VERSION", "v1")
|
||||
next_num = int(current_version.lstrip("v")) + 1
|
||||
next_version = f"v{next_num}"
|
||||
print(f" Current secret version: {current_version}", flush=True)
|
||||
print(f" Inserting as: {next_version}", flush=True)
|
||||
app_secret_insert(DOCS_DOMAIN, "oidc_rpcs", next_version, client_secret)
|
||||
|
||||
# Step 5: Update Docs env with Authentik OIDC settings
|
||||
print("=== Update Docs OIDC settings in env file ===", flush=True)
|
||||
apply_env_overrides(env_path, {
|
||||
"SECRET_OIDC_RPCS_VERSION": next_version,
|
||||
"AUTH_DOMAIN": ak_domain,
|
||||
"OIDC_OP_JWKS_ENDPOINT": f"https://{ak_domain}/application/o/{APP_SLUG}/jwks/",
|
||||
"OIDC_OP_AUTHORIZATION_ENDPOINT": f"https://{ak_domain}/application/o/authorize/",
|
||||
"OIDC_OP_TOKEN_ENDPOINT": f"https://{ak_domain}/application/o/token/",
|
||||
"OIDC_OP_USER_ENDPOINT": f"https://{ak_domain}/application/o/userinfo/",
|
||||
"OIDC_RP_CLIENT_ID": CLIENT_ID,
|
||||
})
|
||||
|
||||
# Step 6: Write credentials file
|
||||
script_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
creds_file = os.path.join(script_dir, f"authentik-test-credentials.{inst.domain_suffix}.toml")
|
||||
print(f"=== Write credentials to {creds_file} ===", flush=True)
|
||||
with open(creds_file, "w") as f:
|
||||
f.write(f'# Authentik OIDC credentials for La Suite Docs (ld2) test instance\n')
|
||||
f.write(f'#\n')
|
||||
f.write(f'# Authentik instance: {ak_domain}\n')
|
||||
f.write(f'# Application slug: {APP_SLUG}\n')
|
||||
f.write(f'# Created by: setup_docs_integration.py\n')
|
||||
f.write(f'\n')
|
||||
f.write(f'# Authentik admin\n')
|
||||
f.write(f'ak_token = "{ak_token}"\n')
|
||||
f.write(f'\n')
|
||||
f.write(f'# OIDC provider\n')
|
||||
f.write(f'ak_app_slug = "{APP_SLUG}"\n')
|
||||
f.write(f'ak_client_id = "{CLIENT_ID}"\n')
|
||||
f.write(f'ak_client_secret = "{client_secret}"\n')
|
||||
f.write(f'\n')
|
||||
f.write(f'# Authentik OIDC endpoints\n')
|
||||
f.write(f'ak_token_endpoint = "https://{ak_domain}/application/o/token/"\n')
|
||||
f.write(f'ak_userinfo_endpoint = "https://{ak_domain}/application/o/userinfo/"\n')
|
||||
f.write(f'ak_discovery_endpoint = "https://{ak_domain}/application/o/{APP_SLUG}/.well-known/openid-configuration"\n')
|
||||
f.write(f'\n')
|
||||
f.write(f'# Test user (password for browser login, app_password for password grant)\n')
|
||||
f.write(f'ak_test_user = "{TEST_USER}"\n')
|
||||
f.write(f'ak_test_pass = "{TEST_PASS}"\n')
|
||||
f.write(f'ak_test_app_password = "{app_password}"\n')
|
||||
f.write(f'ak_test_email = "{TEST_EMAIL}"\n')
|
||||
f.write(f'\n')
|
||||
f.write(f'# Docs instance\n')
|
||||
f.write(f'docs_domain = "{DOCS_DOMAIN}"\n')
|
||||
print(f" Written to {creds_file}", flush=True)
|
||||
|
||||
print("", flush=True)
|
||||
print("=== Authentik OIDC integration setup complete ===", flush=True)
|
||||
print("", flush=True)
|
||||
print("Next steps:", flush=True)
|
||||
print(f" 1. Redeploy Docs: abra app deploy {DOCS_DOMAIN} --chaos --force --no-input", flush=True)
|
||||
print(f" 2. Run OIDC test: python3 recipe-info/authentik/tests/oidc_integration.py", flush=True)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user