Research-Stack/4-Infrastructure/shim/configure_vault_authentik.py
allaun 36a78fec72 feat(infra): add support for secure file-based Authentik token loading
Add support for AUTHENTIK_TOKEN_FILE environment variable fallback to
service_orchestrator.py, configure_vault_authentik.py, and the Rust
authentik_agent_manager CLI/MCP server. This prevents hardcoding or
exposing raw tokens in environment blocks or CLI arguments. Document
the new Authentik SSO stack deployment on cupfox k3s in AGENTS.md and
update .mcp.json.full configuration.

Build: 0 jobs, 0 errors (lake build)
2026-07-05 15:54:27 -05:00

129 lines
5 KiB
Python

#!/usr/bin/env python3
import os
import requests
import json
import sys
TOKEN = os.environ.get("AUTHENTIK_TOKEN")
if not TOKEN:
token_file = os.environ.get("AUTHENTIK_TOKEN_FILE")
if token_file and os.path.exists(token_file):
with open(token_file, "r") as f:
TOKEN = f.read().strip()
if not TOKEN:
TOKEN = "sLYSgzOsIO0elCJXVtpkYkTDtnkkIoGnu10CdbQxjQa6F7EO3QsRbZC3Pf0Z"
BASE_URL = "https://auth.researchstack.info"
OUTPOST_UUID = "1ceb9880-517e-4fe6-acb8-ecc1c8276bf4"
headers = {
"Authorization": f"Bearer {TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json"
}
def main():
# 1. Create or get Proxy Provider
print("Checking if proxy provider 'researchstack-vault' already exists...")
resp = requests.get(f"{BASE_URL}/api/v3/providers/proxy/", headers=headers)
if resp.status_code != 200:
print(f"Error listing providers: {resp.status_code} {resp.text}")
sys.exit(1)
providers = resp.json().get("results", [])
provider_pk = None
for p in providers:
if p.get("name") == "researchstack-vault":
provider_pk = p.get("pk")
print(f"Provider 'researchstack-vault' already exists with PK {provider_pk}")
break
if not provider_pk:
print("Creating proxy provider...")
provider_data = {
"name": "researchstack-vault",
"authentication_flow": "b6a80fb0-d5b9-4475-ab60-e60fb3a8672d",
"authorization_flow": "70aaa90a-83bf-4506-bc63-78234f6021df",
"invalidation_flow": "b5daeb70-7587-4f74-b41b-2b5be06c5477",
"property_mappings": [
"ad30e2ea-1754-4a29-934c-39fbf42a4045",
"4047f976-fbc0-4a75-bc8d-0537f88fc436",
"793af5d2-f445-44e5-9034-e5fe2baeed7a",
"4991aaa7-31ec-4d62-a5e1-95946aacdfdf",
"c894ca75-3c2e-4870-840b-5441bbdd65ea"
],
"internal_host": "http://100.115.119.40:8080",
"external_host": "https://vault.researchstack.info",
"internal_host_ssl_validation": False,
"mode": "forward_single",
"intercept_header_auth": True,
"cookie_domain": "researchstack.info"
}
resp = requests.post(f"{BASE_URL}/api/v3/providers/proxy/", headers=headers, json=provider_data)
if resp.status_code not in (200, 201):
print(f"Error creating provider: {resp.status_code} {resp.text}")
sys.exit(1)
provider_pk = resp.json().get("pk")
print(f"Created proxy provider with PK {provider_pk}")
# 2. Create or get Application
print("Checking if application 'Research Stack Vaultwarden' already exists...")
resp = requests.get(f"{BASE_URL}/api/v3/core/applications/", headers=headers)
if resp.status_code != 200:
print(f"Error listing applications: {resp.status_code} {resp.text}")
sys.exit(1)
apps = resp.json().get("results", [])
app_exists = False
for a in apps:
if a.get("slug") == "researchstack-vault":
app_exists = True
print("Application 'Research Stack Vaultwarden' already exists")
break
if not app_exists:
print("Creating application...")
app_data = {
"name": "Research Stack Vaultwarden",
"slug": "researchstack-vault",
"provider": provider_pk,
"policy_engine_mode": "any"
}
resp = requests.post(f"{BASE_URL}/api/v3/core/applications/", headers=headers, json=app_data)
if resp.status_code not in (200, 201):
print(f"Error creating application: {resp.status_code} {resp.text}")
sys.exit(1)
print("Created application successfully")
# 3. Update Outpost
print("Fetching existing outpost...")
resp = requests.get(f"{BASE_URL}/api/v3/outposts/instances/{OUTPOST_UUID}/", headers=headers)
if resp.status_code != 200:
print(f"Error fetching outpost: {resp.status_code} {resp.text}")
sys.exit(1)
outpost_data = resp.json()
providers_list = outpost_data.get("providers", [])
print(f"Current outpost providers: {providers_list}")
if provider_pk not in providers_list:
providers_list.append(provider_pk)
print(f"Updating outpost with providers: {providers_list}")
# We need to send a PUT or PATCH request.
# PATCH requires name, type, and providers at a minimum
update_data = {
"name": outpost_data.get("name"),
"type": outpost_data.get("type"),
"providers": providers_list
}
resp = requests.patch(f"{BASE_URL}/api/v3/outposts/instances/{OUTPOST_UUID}/", headers=headers, json=update_data)
if resp.status_code != 200:
print(f"Error updating outpost: {resp.status_code} {resp.text}")
sys.exit(1)
print("Outpost updated successfully with new provider!")
else:
print("Provider already assigned to outpost.")
if __name__ == "__main__":
main()