Add optional SMTP configuration for Authentik, including email host, port, and credentials. Update README and .env.sample to clarify usage for outbound email settings. Introduce blueprint support for enhanced deployment flexibility, with assertions in Ansible tasks to ensure required variables are set when enabled.
This commit is contained in:
10
.env.sample
10
.env.sample
@@ -38,3 +38,13 @@ NOBLE_AUTHENTIK_MEDIA_S3_BUCKET=
|
|||||||
# NOBLE_AUTHENTIK_S3_SECRET_KEY=
|
# NOBLE_AUTHENTIK_S3_SECRET_KEY=
|
||||||
# NOBLE_AUTHENTIK_S3_REGION=
|
# NOBLE_AUTHENTIK_S3_REGION=
|
||||||
# NOBLE_AUTHENTIK_S3_ADDRESSING_STYLE=
|
# NOBLE_AUTHENTIK_S3_ADDRESSING_STYLE=
|
||||||
|
#
|
||||||
|
# Optional outbound email (password recovery, invites, etc.) — maps to Authentik **AUTHENTIK_EMAIL__*** (see https://docs.goauthentik.io/install-config/configuration/#email-settings ). Omit **NOBLE_AUTHENTIK_SMTP_HOST** to leave email unset in Helm.
|
||||||
|
# NOBLE_AUTHENTIK_SMTP_HOST=
|
||||||
|
# NOBLE_AUTHENTIK_SMTP_FROM=
|
||||||
|
# NOBLE_AUTHENTIK_SMTP_PORT=587
|
||||||
|
# NOBLE_AUTHENTIK_SMTP_USERNAME=
|
||||||
|
# NOBLE_AUTHENTIK_SMTP_PASSWORD=
|
||||||
|
# NOBLE_AUTHENTIK_SMTP_USE_TLS=true
|
||||||
|
# NOBLE_AUTHENTIK_SMTP_USE_SSL=false
|
||||||
|
# NOBLE_AUTHENTIK_SMTP_TIMEOUT=30
|
||||||
|
|||||||
@@ -184,7 +184,7 @@ Shared services used across multiple applications.
|
|||||||
|
|
||||||
- **[Versity S3 Gateway](https://github.com/versity/versitygw)** — S3 API on port **10000** by default; optional **WebUI** on **8080** (not the same listener—enable `VERSITYGW_WEBUI_PORT` / `VGW_WEBUI_GATEWAYS` per `.env.sample`). Behind **Pangolin**, expose the API and WebUI separately (or you will see **404** browsing the API URL).
|
- **[Versity S3 Gateway](https://github.com/versity/versitygw)** — S3 API on port **10000** by default; optional **WebUI** on **8080** (not the same listener—enable `VERSITYGW_WEBUI_PORT` / `VGW_WEBUI_GATEWAYS` per `.env.sample`). Behind **Pangolin**, expose the API and WebUI separately (or you will see **404** browsing the API URL).
|
||||||
|
|
||||||
**Configuration:** Set either `ROOT_ACCESS_KEY` / `ROOT_SECRET_KEY` or `ROOT_ACCESS_KEY_ID` / `ROOT_SECRET_ACCESS_KEY`. Optional `VERSITYGW_PORT`. Compose uses `${VAR}` interpolation so credentials work with Komodo’s `docker compose --env-file <run_directory>/.env` (avoid `env_file:` in the service when `run_directory` is not the same folder as `compose.yaml`, or the written `.env` will not be found).
|
**Configuration:** Set either `ROOT_ACCESS_KEY` / `ROOT_SECRET_KEY` or `ROOT_ACCESS_KEY_ID` / `ROOT_SECRET_ACCESS_KEY`. Optional `VERSITYGW_PORT`. For a browser UI on another host (for example `https://s3-ui.pcenicni.dev` calling the API through Pangolin), set **`VGW_CORS_ALLOW_ORIGIN`** to that UI origin; VersityGW reflects requested headers on preflight when bucket CORS is unset (see `.env.sample`). If that is already set and CORS still fails, **Pangolin** may be handling **OPTIONS** before Versity (for example auth on the public resource blocking preflight; see `komodo/s3/versitygw/.env.sample` § Pangolin). Compose uses `${VAR}` interpolation so credentials work with Komodo’s `docker compose --env-file <run_directory>/.env` (avoid `env_file:` in the service when `run_directory` is not the same folder as `compose.yaml`, or the written `.env` will not be found).
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -30,3 +30,4 @@ noble_authentik_install: true
|
|||||||
# Optional: public (or extra) Authentik hostnames on the same IdP — list of FQDNs. Pangolin: CNAME + resource → Newt → Traefik (see noble_authentik README).
|
# Optional: public (or extra) Authentik hostnames on the same IdP — list of FQDNs. Pangolin: CNAME + resource → Newt → Traefik (see noble_authentik README).
|
||||||
noble_authentik_ingress_extra_hosts:
|
noble_authentik_ingress_extra_hosts:
|
||||||
- auth.nikflix.ca
|
- auth.nikflix.ca
|
||||||
|
noble_authentik_blueprints_enabled: true
|
||||||
@@ -4,7 +4,7 @@ Installs **Authentik** (Helm `goauthentik/authentik`) as the cluster IdP, **oaut
|
|||||||
|
|
||||||
## Enable
|
## Enable
|
||||||
|
|
||||||
1. Copy repository **`.env.sample`** to **`.env`** and set every **`NOBLE_AUTHENTIK_*`** variable (see comments there).
|
1. Copy repository **`.env.sample`** to **`.env`** and set all **required** **`NOBLE_AUTHENTIK_*`** values (see comments there; SMTP keys are optional).
|
||||||
2. Set **`noble_authentik_install: true`** in **`ansible/inventory/group_vars/all.yml`** (or pass **`-e noble_authentik_install=true`**).
|
2. Set **`noble_authentik_install: true`** in **`ansible/inventory/group_vars/all.yml`** (or pass **`-e noble_authentik_install=true`**).
|
||||||
3. Run **`ansible-playbook playbooks/noble.yml --tags authentik`** (or a full **`noble.yml`**) from **`ansible/`** with a working **`KUBECONFIG`**.
|
3. Run **`ansible-playbook playbooks/noble.yml --tags authentik`** (or a full **`noble.yml`**) from **`ansible/`** with a working **`KUBECONFIG`**.
|
||||||
|
|
||||||
@@ -18,13 +18,43 @@ See **`defaults/main.yml`**. Hostnames default to **`auth.apps.noble.lab.pcenicn
|
|||||||
|
|
||||||
Authentik stores file-backed data in **S3** (not a shared PVC on **`authentik-worker`**). Set **`NOBLE_AUTHENTIK_MEDIA_S3_BUCKET`** in **`.env`** to a **dedicated** bucket name (do **not** reuse the Velero backup bucket). **`NOBLE_VELERO_S3_URL`**, **`NOBLE_VELERO_AWS_ACCESS_KEY_ID`**, and **`NOBLE_VELERO_AWS_SECRET_ACCESS_KEY`** are reused automatically when the Authentik-specific S3 variables are unset; override with **`NOBLE_AUTHENTIK_S3_URL`** / **`NOBLE_AUTHENTIK_S3_ACCESS_KEY`** / **`NOBLE_AUTHENTIK_S3_SECRET_KEY`** if needed. Optional: **`NOBLE_AUTHENTIK_S3_REGION`** (defaults to **`us-east-1`** in Ansible), **`NOBLE_AUTHENTIK_S3_ADDRESSING_STYLE`** (**`path`** vs **`virtual`** for some gateways). Create the bucket and grant the same credentials **read/write** to that bucket only. For browser uploads and public assets, follow [Authentik — S3 storage](https://docs.goauthentik.io/sys-mgmt/ops/storage-s3/) (CORS and policies). If you previously used a PVC for **`/data`**, sync into the new bucket (for example **`aws s3 sync`** from a volume snapshot or old mount) before relying on S3-only.
|
Authentik stores file-backed data in **S3** (not a shared PVC on **`authentik-worker`**). Set **`NOBLE_AUTHENTIK_MEDIA_S3_BUCKET`** in **`.env`** to a **dedicated** bucket name (do **not** reuse the Velero backup bucket). **`NOBLE_VELERO_S3_URL`**, **`NOBLE_VELERO_AWS_ACCESS_KEY_ID`**, and **`NOBLE_VELERO_AWS_SECRET_ACCESS_KEY`** are reused automatically when the Authentik-specific S3 variables are unset; override with **`NOBLE_AUTHENTIK_S3_URL`** / **`NOBLE_AUTHENTIK_S3_ACCESS_KEY`** / **`NOBLE_AUTHENTIK_S3_SECRET_KEY`** if needed. Optional: **`NOBLE_AUTHENTIK_S3_REGION`** (defaults to **`us-east-1`** in Ansible), **`NOBLE_AUTHENTIK_S3_ADDRESSING_STYLE`** (**`path`** vs **`virtual`** for some gateways). Create the bucket and grant the same credentials **read/write** to that bucket only. For browser uploads and public assets, follow [Authentik — S3 storage](https://docs.goauthentik.io/sys-mgmt/ops/storage-s3/) (CORS and policies). If you previously used a PVC for **`/data`**, sync into the new bucket (for example **`aws s3 sync`** from a volume snapshot or old mount) before relying on S3-only.
|
||||||
|
|
||||||
|
### Outbound email (SMTP)
|
||||||
|
|
||||||
|
Optional. Set **`NOBLE_AUTHENTIK_SMTP_HOST`** and **`NOBLE_AUTHENTIK_SMTP_FROM`** in repository **`.env`**; Ansible adds **`AUTHENTIK_EMAIL__HOST`**, **`AUTHENTIK_EMAIL__FROM`**, and related variables to Helm **`global.env`** (see [Authentik configuration — email](https://docs.goauthentik.io/install-config/configuration/#email-settings)). Omit **`NOBLE_AUTHENTIK_SMTP_HOST`** to skip SMTP env vars entirely. Optional overrides: **`NOBLE_AUTHENTIK_SMTP_PORT`** (default **587** in **`defaults/main.yml`**), **`NOBLE_AUTHENTIK_SMTP_USERNAME`**, **`NOBLE_AUTHENTIK_SMTP_PASSWORD`**, **`NOBLE_AUTHENTIK_SMTP_USE_TLS`** / **`USE_SSL`** / **`TIMEOUT`**. Re-run **`ansible-playbook playbooks/noble.yml --tags authentik`** after changes.
|
||||||
|
|
||||||
### Extra public hostname (Pangolin + Newt, same Authentik)
|
### Extra public hostname (Pangolin + Newt, same Authentik)
|
||||||
|
|
||||||
To expose the **same** Authentik instance on an **internet-facing** FQDN (while keeping the lab name on Traefik), set **`noble_authentik_ingress_extra_hosts`** in **`ansible/inventory/group_vars/all.yml`** (or **`-e`**) to a list of extra FQDNs, for example **`auth.example.com`**. Re-run **`ansible-playbook playbooks/noble.yml --tags authentik`**. Ansible extends **`server.ingress.hosts`** and **`tls[0].hosts`** so **cert-manager** issues one certificate with SANs for the primary **`noble_authentik_host`** plus those names (DNS must resolve for your issuer — often **Cloudflare** for public names, split horizon for lab).
|
To expose the **same** Authentik instance on an **internet-facing** FQDN (while keeping the lab name on Traefik), set **`noble_authentik_ingress_extra_hosts`** in **`ansible/inventory/group_vars/all.yml`** (or **`-e`**) to a list of extra FQDNs, for example **`auth.example.com`**. Re-run **`ansible-playbook playbooks/noble.yml --tags authentik`**. Ansible extends **`server.ingress.hosts`** and **`tls[0].hosts`** so **cert-manager** issues one certificate with SANs for the primary **`noble_authentik_host`** plus those names (DNS must resolve for your issuer — often **Cloudflare** for public names, split horizon for lab).
|
||||||
|
|
||||||
Then in **Pangolin**: link the domain, create an **HTTP** resource for that hostname, and set the **target** to your **Newt** site with **`ip:port`** pointing at the cluster **Traefik** HTTPS entry (same pattern as **`clusters/noble/bootstrap/newt/README.md`** — typically the MetalLB / LAN VIP and **443**). One Newt tunnel can front many hostnames.
|
Then in **Pangolin**: link the domain, create an **HTTP** resource for that hostname, and set the **target** to your **Newt** site with **`ip:port`** pointing at the cluster **Traefik** HTTPS entry (same pattern as **`clusters/noble/bootstrap/newt/README.md`** — typically the MetalLB / LAN VIP and **443**). One Newt tunnel can front many hostnames.
|
||||||
|
|
||||||
In **Authentik**, add a **Brand** (or equivalent) for the new hostname if you want different titles/favicon; OAuth **redirect URIs** for each app must include issuer URLs that match what browsers use (often you keep **internal** issuer URLs in cluster apps and use the public URL only for human login, or align all apps to the public issuer — pick one strategy to avoid mixed **`iss`** / callback mismatches).
|
### Split routing, two Brands, and optional blueprints
|
||||||
|
|
||||||
|
This role supports a **single Authentik deployment** with **two hostnames** (lab + public) and **different Brands** per **`Host`**, without Authentik’s separate-database **Tenancy** feature (see [Tenancy](https://docs.goauthentik.io/sys-mgmt/tenancy) — alpha / licensing). [Brands](https://docs.goauthentik.io/brands/) choose default **authentication** (and related) **flows** and branding for each FQDN.
|
||||||
|
|
||||||
|
**Split routing (recommended):**
|
||||||
|
|
||||||
|
- **Lab / operator URL** — **`noble_authentik_host`** (default **`auth.apps.noble.lab.pcenicni.dev`**): keep DNS **internal-only** (split horizon, VPN, or LAN DNS). Do **not** publish this hostname as a Pangolin HTTP resource toward the internet unless you intentionally want it reachable off-LAN.
|
||||||
|
- **Public URL** — entries in **`noble_authentik_ingress_extra_hosts`**: use Pangolin (or another edge) only for these names so casual users never need the lab FQDN.
|
||||||
|
|
||||||
|
Network isolation is enforced at **DNS and the tunnel**, not inside Authentik. Optionally add firewall / Traefik entrypoint rules for defense in depth.
|
||||||
|
|
||||||
|
**Two-Brand model:**
|
||||||
|
|
||||||
|
- **Lab Brand** — domain equals **`noble_authentik_host`**: use a **restricted authentication flow** so only operator groups (defaults: **`noble-admins`**, **`authentik Admins`**) can complete sign-in on that hostname. Your bootstrap / break-glass account must remain in one of those groups (see **`noble_authentik_ensure_admin_ui_access`** and **`configure_authentik.py`** group membership).
|
||||||
|
- **Public Brand(s)** — one Brand per FQDN in **`noble_authentik_ingress_extra_hosts`**: use the stock **`default-authentication-flow`** (or replace with your own flow slug via a forked blueprint later). Assign general users to **`noble_authentik_blueprint_public_groups`** (defaults **`noble-public-users`**, **`noble-public-admins`**) for app policies and OAuth claims; **`noble-admins`** / **`noble-editors`** remain for cluster / Argo / Grafana as today.
|
||||||
|
|
||||||
|
**OAuth note:** Redirect URIs and **`iss`** must stay consistent with the hostname clients use (internal issuer for in-cluster apps vs public issuer is a deliberate choice — avoid mixing both for the same app).
|
||||||
|
|
||||||
|
**Mounted blueprints (optional):** set **`noble_authentik_blueprints_enabled: true`** in **`group_vars`** (or **`-e`**). On each **`--tags authentik`** run, Ansible renders Jinja templates under **`templates/blueprints/`** into a ConfigMap **`noble_authentik_blueprints_configmap_name`** (default **`authentik-noble-blueprints`**) and sets Helm **`blueprints.configMaps`** so **authentik-worker** loads them from **`/blueprints/mounted/cm-authentik-noble-blueprints/`** (see [Blueprints](https://docs.goauthentik.io/customize/blueprints/)). Files (apply in lexical order):
|
||||||
|
|
||||||
|
| Key | Purpose |
|
||||||
|
| --- | --- |
|
||||||
|
| **`10-noble-public-groups.yaml.j2`** | Ensures **`noble_authentik_blueprint_public_groups`** exist. |
|
||||||
|
| **`20-noble-lab-operator-authentication-flow.yaml.j2`** | Flow **`noble_authentik_blueprint_lab_flow_slug`** + expression policy **`noble_authentik_blueprint_operator_policy_name`** (allowed groups **`noble_authentik_blueprint_lab_operator_groups`**). |
|
||||||
|
| **`30-noble-brands-domain-split.yaml.j2`** | Brand for **`noble_authentik_host`** → lab flow; one Brand per **`noble_authentik_ingress_extra_hosts`** → default authentication. |
|
||||||
|
|
||||||
|
Tune titles via **`noble_authentik_blueprint_lab_brand_title`** and **`noble_authentik_blueprint_public_brand_title_prefix`**. After the worker applies blueprints, confirm **System → Brands** and **Flows** in the admin UI; fix any **`!Find`** failures if upstream default stage **names** change between Authentik versions.
|
||||||
|
|
||||||
### “Secondary tenant” (separate PostgreSQL schema — alpha)
|
### “Secondary tenant” (separate PostgreSQL schema — alpha)
|
||||||
|
|
||||||
@@ -41,6 +71,7 @@ When **`noble_authentik_configure_idp`** is true, Ansible creates/updates OAuth2
|
|||||||
|
|
||||||
## Troubleshooting
|
## Troubleshooting
|
||||||
|
|
||||||
|
- **Blueprints from Ansible fail to apply** (worker logs / **System → Blueprints**): confirm the ConfigMap exists (**`kubectl -n authentik get cm authentik-noble-blueprints`** unless you changed **`noble_authentik_blueprints_configmap_name`**), that Helm mounts it (**`blueprints.configMaps`** in the rendered extra values), and that every **`!Find`** in **`templates/blueprints/20-*.j2`** still matches your Authentik version’s default stage **names**. Re-run **`--tags authentik`** after editing templates.
|
||||||
- **oauth2-proxy shows 500** on **`oauth2.apps…/oauth2/callback`** (logs: `email in id_token (...) isn't verified`): Authentik’s id_token often lacks **`email_verified: true`** for bootstrap users. **`clusters/noble/bootstrap/oauth2-proxy/values.yaml`** sets **`insecure-oidc-allow-unverified-email`** for the lab; otherwise verify the user’s email in Authentik, then **`helm upgrade oauth2-proxy`** (or **`--tags authentik`**).
|
- **oauth2-proxy shows 500** on **`oauth2.apps…/oauth2/callback`** (logs: `email in id_token (...) isn't verified`): Authentik’s id_token often lacks **`email_verified: true`** for bootstrap users. **`clusters/noble/bootstrap/oauth2-proxy/values.yaml`** sets **`insecure-oidc-allow-unverified-email`** for the lab; otherwise verify the user’s email in Authentik, then **`helm upgrade oauth2-proxy`** (or **`--tags authentik`**).
|
||||||
- Re-run **`configure_authentik.py`** only by executing **`noble.yml`** with **`--tags authentik`** after fixing `.env`.
|
- Re-run **`configure_authentik.py`** only by executing **`noble.yml`** with **`--tags authentik`** after fixing `.env`.
|
||||||
- If Authentik API calls fail, check flows exist (slug **`default-provider-authorization-implicit-consent`**) and TLS reaches **`AUTHENTIK_API_BASE`**.
|
- If Authentik API calls fail, check flows exist (slug **`default-provider-authorization-implicit-consent`**) and TLS reaches **`AUTHENTIK_API_BASE`**.
|
||||||
|
|||||||
@@ -26,6 +26,24 @@ noble_authentik_api_base: "{{ noble_authentik_public_url }}/api/v3"
|
|||||||
# Ansible merges these into **server.ingress.hosts** / **tls** (one cert Secret with multiple SANs).
|
# Ansible merges these into **server.ingress.hosts** / **tls** (one cert Secret with multiple SANs).
|
||||||
noble_authentik_ingress_extra_hosts: []
|
noble_authentik_ingress_extra_hosts: []
|
||||||
|
|
||||||
|
# Mounted **blueprints** (ConfigMap → worker `/blueprints/mounted/cm-*`). See README § split routing / two-Brand.
|
||||||
|
noble_authentik_blueprints_enabled: false
|
||||||
|
noble_authentik_blueprints_configmap_name: authentik-noble-blueprints
|
||||||
|
# Directory groups for the public Brand(s); adjust names to match your apps’ policies / OAuth claims.
|
||||||
|
noble_authentik_blueprint_public_groups:
|
||||||
|
- noble-public-users
|
||||||
|
- noble-public-admins
|
||||||
|
# Lab-only authentication flow slug (Brand for **`noble_authentik_host`** points here).
|
||||||
|
noble_authentik_blueprint_lab_flow_slug: noble-lab-operator-authentication-flow
|
||||||
|
noble_authentik_blueprint_operator_policy_name: noble-lab-operators-only
|
||||||
|
# Who may sign in on the **lab** hostname (`noble_authentik_host`). Bootstrap user should be in **noble-admins**
|
||||||
|
# and/or **authentik Admins** (see **`noble_authentik_ensure_admin_ui_access`**).
|
||||||
|
noble_authentik_blueprint_lab_operator_groups:
|
||||||
|
- noble-admins
|
||||||
|
- authentik Admins
|
||||||
|
noble_authentik_blueprint_lab_brand_title: Noble lab (operators)
|
||||||
|
noble_authentik_blueprint_public_brand_title_prefix: Noble public
|
||||||
|
|
||||||
noble_authentik_oauth2_proxy_host: oauth2.apps.noble.lab.pcenicni.dev
|
noble_authentik_oauth2_proxy_host: oauth2.apps.noble.lab.pcenicni.dev
|
||||||
|
|
||||||
# Media: **S3** via Ansible **`global.env`** (same S3 **URL** + **access keys** as **Velero** when you omit Authentik-specific overrides).
|
# Media: **S3** via Ansible **`global.env`** (same S3 **URL** + **access keys** as **Velero** when you omit Authentik-specific overrides).
|
||||||
@@ -37,6 +55,17 @@ noble_authentik_s3_secret_key: ""
|
|||||||
noble_authentik_s3_region: "us-east-1"
|
noble_authentik_s3_region: "us-east-1"
|
||||||
noble_authentik_s3_addressing_style: "path"
|
noble_authentik_s3_addressing_style: "path"
|
||||||
|
|
||||||
|
# Optional outbound SMTP (maps to **AUTHENTIK_EMAIL__*** in Helm **global.env**). Leave **noble_authentik_smtp_host**
|
||||||
|
# empty to omit email env vars; set **NOBLE_AUTHENTIK_SMTP_HOST** (and **NOBLE_AUTHENTIK_SMTP_FROM**) in **.env** to enable.
|
||||||
|
noble_authentik_smtp_host: ""
|
||||||
|
noble_authentik_smtp_port: "587"
|
||||||
|
noble_authentik_smtp_username: ""
|
||||||
|
noble_authentik_smtp_password: ""
|
||||||
|
noble_authentik_smtp_use_tls: "true"
|
||||||
|
noble_authentik_smtp_use_ssl: "false"
|
||||||
|
noble_authentik_smtp_timeout: "30"
|
||||||
|
noble_authentik_smtp_from: ""
|
||||||
|
|
||||||
# OIDC client ids (must match Authentik providers created by configure script)
|
# OIDC client ids (must match Authentik providers created by configure script)
|
||||||
noble_authentik_client_id_argocd: argocd
|
noble_authentik_client_id_argocd: argocd
|
||||||
noble_authentik_client_id_grafana: grafana
|
noble_authentik_client_id_grafana: grafana
|
||||||
|
|||||||
@@ -349,3 +349,168 @@
|
|||||||
- noble_authentik_s3_addr_from_env is defined
|
- noble_authentik_s3_addr_from_env is defined
|
||||||
- (noble_authentik_s3_addr_from_env.stdout | default('') | trim | length) > 0
|
- (noble_authentik_s3_addr_from_env.stdout | default('') | trim | length) > 0
|
||||||
no_log: true
|
no_log: true
|
||||||
|
|
||||||
|
# --- Optional SMTP (AUTHENTIK_EMAIL__* via Helm global.env) ---
|
||||||
|
- name: Load NOBLE_AUTHENTIK_SMTP_HOST from .env when unset
|
||||||
|
ansible.builtin.shell: |
|
||||||
|
set -a
|
||||||
|
. "{{ noble_repo_root }}/.env"
|
||||||
|
set +a
|
||||||
|
printf '%s' "${NOBLE_AUTHENTIK_SMTP_HOST:-}"
|
||||||
|
register: noble_authentik_smtp_host_from_env
|
||||||
|
when:
|
||||||
|
- noble_authentik_dotenv_stat.stat.exists | default(false)
|
||||||
|
- noble_authentik_smtp_host | default('') | length == 0
|
||||||
|
changed_when: false
|
||||||
|
no_log: true
|
||||||
|
|
||||||
|
- name: Apply NOBLE_AUTHENTIK_SMTP_HOST from .env
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
noble_authentik_smtp_host: "{{ noble_authentik_smtp_host_from_env.stdout | trim }}"
|
||||||
|
when:
|
||||||
|
- noble_authentik_smtp_host_from_env is defined
|
||||||
|
- (noble_authentik_smtp_host_from_env.stdout | default('') | trim | length) > 0
|
||||||
|
no_log: true
|
||||||
|
|
||||||
|
- name: Load NOBLE_AUTHENTIK_SMTP_FROM from .env when unset
|
||||||
|
ansible.builtin.shell: |
|
||||||
|
set -a
|
||||||
|
. "{{ noble_repo_root }}/.env"
|
||||||
|
set +a
|
||||||
|
printf '%s' "${NOBLE_AUTHENTIK_SMTP_FROM:-}"
|
||||||
|
register: noble_authentik_smtp_from_from_env
|
||||||
|
when:
|
||||||
|
- noble_authentik_dotenv_stat.stat.exists | default(false)
|
||||||
|
- noble_authentik_smtp_from | default('') | length == 0
|
||||||
|
changed_when: false
|
||||||
|
no_log: true
|
||||||
|
|
||||||
|
- name: Apply NOBLE_AUTHENTIK_SMTP_FROM from .env
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
noble_authentik_smtp_from: "{{ noble_authentik_smtp_from_from_env.stdout | trim }}"
|
||||||
|
when:
|
||||||
|
- noble_authentik_smtp_from_from_env is defined
|
||||||
|
- (noble_authentik_smtp_from_from_env.stdout | default('') | trim | length) > 0
|
||||||
|
no_log: true
|
||||||
|
|
||||||
|
- name: Load NOBLE_AUTHENTIK_SMTP_USERNAME from .env when unset
|
||||||
|
ansible.builtin.shell: |
|
||||||
|
set -a
|
||||||
|
. "{{ noble_repo_root }}/.env"
|
||||||
|
set +a
|
||||||
|
printf '%s' "${NOBLE_AUTHENTIK_SMTP_USERNAME:-}"
|
||||||
|
register: noble_authentik_smtp_username_from_env
|
||||||
|
when:
|
||||||
|
- noble_authentik_dotenv_stat.stat.exists | default(false)
|
||||||
|
- noble_authentik_smtp_username | default('') | length == 0
|
||||||
|
changed_when: false
|
||||||
|
no_log: true
|
||||||
|
|
||||||
|
- name: Apply NOBLE_AUTHENTIK_SMTP_USERNAME from .env
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
noble_authentik_smtp_username: "{{ noble_authentik_smtp_username_from_env.stdout | trim }}"
|
||||||
|
when:
|
||||||
|
- noble_authentik_smtp_username_from_env is defined
|
||||||
|
- (noble_authentik_smtp_username_from_env.stdout | default('') | trim | length) > 0
|
||||||
|
no_log: true
|
||||||
|
|
||||||
|
- name: Load NOBLE_AUTHENTIK_SMTP_PASSWORD from .env when unset
|
||||||
|
ansible.builtin.shell: |
|
||||||
|
set -a
|
||||||
|
. "{{ noble_repo_root }}/.env"
|
||||||
|
set +a
|
||||||
|
printf '%s' "${NOBLE_AUTHENTIK_SMTP_PASSWORD:-}"
|
||||||
|
register: noble_authentik_smtp_password_from_env
|
||||||
|
when:
|
||||||
|
- noble_authentik_dotenv_stat.stat.exists | default(false)
|
||||||
|
- noble_authentik_smtp_password | default('') | length == 0
|
||||||
|
changed_when: false
|
||||||
|
no_log: true
|
||||||
|
|
||||||
|
- name: Apply NOBLE_AUTHENTIK_SMTP_PASSWORD from .env
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
noble_authentik_smtp_password: "{{ noble_authentik_smtp_password_from_env.stdout | trim }}"
|
||||||
|
when:
|
||||||
|
- noble_authentik_smtp_password_from_env is defined
|
||||||
|
- (noble_authentik_smtp_password_from_env.stdout | default('') | trim | length) > 0
|
||||||
|
no_log: true
|
||||||
|
|
||||||
|
- name: Load NOBLE_AUTHENTIK_SMTP_PORT from .env
|
||||||
|
ansible.builtin.shell: |
|
||||||
|
set -a
|
||||||
|
. "{{ noble_repo_root }}/.env"
|
||||||
|
set +a
|
||||||
|
printf '%s' "${NOBLE_AUTHENTIK_SMTP_PORT:-}"
|
||||||
|
register: noble_authentik_smtp_port_from_env
|
||||||
|
when:
|
||||||
|
- noble_authentik_dotenv_stat.stat.exists | default(false)
|
||||||
|
changed_when: false
|
||||||
|
no_log: true
|
||||||
|
|
||||||
|
- name: Apply NOBLE_AUTHENTIK_SMTP_PORT from .env
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
noble_authentik_smtp_port: "{{ noble_authentik_smtp_port_from_env.stdout | trim }}"
|
||||||
|
when:
|
||||||
|
- noble_authentik_smtp_port_from_env is defined
|
||||||
|
- (noble_authentik_smtp_port_from_env.stdout | default('') | trim | length) > 0
|
||||||
|
no_log: true
|
||||||
|
|
||||||
|
- name: Load NOBLE_AUTHENTIK_SMTP_USE_TLS from .env
|
||||||
|
ansible.builtin.shell: |
|
||||||
|
set -a
|
||||||
|
. "{{ noble_repo_root }}/.env"
|
||||||
|
set +a
|
||||||
|
printf '%s' "${NOBLE_AUTHENTIK_SMTP_USE_TLS:-}"
|
||||||
|
register: noble_authentik_smtp_use_tls_from_env
|
||||||
|
when:
|
||||||
|
- noble_authentik_dotenv_stat.stat.exists | default(false)
|
||||||
|
changed_when: false
|
||||||
|
no_log: true
|
||||||
|
|
||||||
|
- name: Apply NOBLE_AUTHENTIK_SMTP_USE_TLS from .env
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
noble_authentik_smtp_use_tls: "{{ noble_authentik_smtp_use_tls_from_env.stdout | trim }}"
|
||||||
|
when:
|
||||||
|
- noble_authentik_smtp_use_tls_from_env is defined
|
||||||
|
- (noble_authentik_smtp_use_tls_from_env.stdout | default('') | trim | length) > 0
|
||||||
|
no_log: true
|
||||||
|
|
||||||
|
- name: Load NOBLE_AUTHENTIK_SMTP_USE_SSL from .env
|
||||||
|
ansible.builtin.shell: |
|
||||||
|
set -a
|
||||||
|
. "{{ noble_repo_root }}/.env"
|
||||||
|
set +a
|
||||||
|
printf '%s' "${NOBLE_AUTHENTIK_SMTP_USE_SSL:-}"
|
||||||
|
register: noble_authentik_smtp_use_ssl_from_env
|
||||||
|
when:
|
||||||
|
- noble_authentik_dotenv_stat.stat.exists | default(false)
|
||||||
|
changed_when: false
|
||||||
|
no_log: true
|
||||||
|
|
||||||
|
- name: Apply NOBLE_AUTHENTIK_SMTP_USE_SSL from .env
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
noble_authentik_smtp_use_ssl: "{{ noble_authentik_smtp_use_ssl_from_env.stdout | trim }}"
|
||||||
|
when:
|
||||||
|
- noble_authentik_smtp_use_ssl_from_env is defined
|
||||||
|
- (noble_authentik_smtp_use_ssl_from_env.stdout | default('') | trim | length) > 0
|
||||||
|
no_log: true
|
||||||
|
|
||||||
|
- name: Load NOBLE_AUTHENTIK_SMTP_TIMEOUT from .env
|
||||||
|
ansible.builtin.shell: |
|
||||||
|
set -a
|
||||||
|
. "{{ noble_repo_root }}/.env"
|
||||||
|
set +a
|
||||||
|
printf '%s' "${NOBLE_AUTHENTIK_SMTP_TIMEOUT:-}"
|
||||||
|
register: noble_authentik_smtp_timeout_from_env
|
||||||
|
when:
|
||||||
|
- noble_authentik_dotenv_stat.stat.exists | default(false)
|
||||||
|
changed_when: false
|
||||||
|
no_log: true
|
||||||
|
|
||||||
|
- name: Apply NOBLE_AUTHENTIK_SMTP_TIMEOUT from .env
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
noble_authentik_smtp_timeout: "{{ noble_authentik_smtp_timeout_from_env.stdout | trim }}"
|
||||||
|
when:
|
||||||
|
- noble_authentik_smtp_timeout_from_env is defined
|
||||||
|
- (noble_authentik_smtp_timeout_from_env.stdout | default('') | trim | length) > 0
|
||||||
|
no_log: true
|
||||||
|
|||||||
@@ -39,6 +39,15 @@
|
|||||||
or reuse Velero's NOBLE_VELERO_S3_URL and NOBLE_VELERO_AWS_ACCESS_KEY_ID / NOBLE_VELERO_AWS_SECRET_ACCESS_KEY
|
or reuse Velero's NOBLE_VELERO_S3_URL and NOBLE_VELERO_AWS_ACCESS_KEY_ID / NOBLE_VELERO_AWS_SECRET_ACCESS_KEY
|
||||||
in .env (see .env.sample and clusters/noble/bootstrap/velero/README.md).
|
in .env (see .env.sample and clusters/noble/bootstrap/velero/README.md).
|
||||||
|
|
||||||
|
- name: Require Authentik SMTP From when SMTP host is set
|
||||||
|
ansible.builtin.assert:
|
||||||
|
that:
|
||||||
|
- noble_authentik_smtp_from | default('') | trim | length > 0
|
||||||
|
fail_msg: >-
|
||||||
|
When NOBLE_AUTHENTIK_SMTP_HOST is set, set NOBLE_AUTHENTIK_SMTP_FROM (sender address).
|
||||||
|
See repository .env.sample and https://docs.goauthentik.io/install-config/configuration/#email-settings
|
||||||
|
when: noble_authentik_smtp_host | default('') | trim | length > 0
|
||||||
|
|
||||||
- name: Ensure Ansible temp dir for rendered Helm values
|
- name: Ensure Ansible temp dir for rendered Helm values
|
||||||
ansible.builtin.file:
|
ansible.builtin.file:
|
||||||
path: "{{ noble_repo_root }}/ansible/.ansible-tmp"
|
path: "{{ noble_repo_root }}/ansible/.ansible-tmp"
|
||||||
@@ -65,6 +74,47 @@
|
|||||||
KUBECONFIG: "{{ noble_kubeconfig }}"
|
KUBECONFIG: "{{ noble_kubeconfig }}"
|
||||||
changed_when: true
|
changed_when: true
|
||||||
|
|
||||||
|
- name: Ensure dir for rendered Authentik blueprints
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ noble_repo_root }}/ansible/.ansible-tmp/authentik-blueprints"
|
||||||
|
state: directory
|
||||||
|
mode: "0700"
|
||||||
|
when: noble_authentik_blueprints_enabled | default(false) | bool
|
||||||
|
|
||||||
|
- name: Assert noble Authentik blueprint variables (when blueprints enabled)
|
||||||
|
ansible.builtin.assert:
|
||||||
|
that:
|
||||||
|
- noble_authentik_blueprint_public_groups | default([]) | length > 0
|
||||||
|
- noble_authentik_blueprint_lab_operator_groups | default([]) | length > 0
|
||||||
|
- noble_authentik_blueprint_lab_flow_slug | default('') | trim | length > 0
|
||||||
|
fail_msg: >-
|
||||||
|
When noble_authentik_blueprints_enabled is true, set noble_authentik_blueprint_public_groups (non-empty),
|
||||||
|
noble_authentik_blueprint_lab_operator_groups (non-empty), and noble_authentik_blueprint_lab_flow_slug.
|
||||||
|
See ansible/roles/noble_authentik/defaults/main.yml and README.
|
||||||
|
when: noble_authentik_blueprints_enabled | default(false) | bool
|
||||||
|
|
||||||
|
- name: Render Authentik noble blueprint YAML files
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: "blueprints/{{ item }}.j2"
|
||||||
|
dest: "{{ noble_repo_root }}/ansible/.ansible-tmp/authentik-blueprints/{{ item }}"
|
||||||
|
mode: "0600"
|
||||||
|
loop:
|
||||||
|
- 10-noble-public-groups.yaml
|
||||||
|
- 20-noble-lab-operator-authentication-flow.yaml
|
||||||
|
- 30-noble-brands-domain-split.yaml
|
||||||
|
when: noble_authentik_blueprints_enabled | default(false) | bool
|
||||||
|
|
||||||
|
- name: Apply Authentik noble blueprints ConfigMap (worker mounts under /blueprints/mounted/cm-*)
|
||||||
|
ansible.builtin.shell: |
|
||||||
|
set -euo pipefail
|
||||||
|
kubectl -n "{{ noble_authentik_namespace }}" create configmap "{{ noble_authentik_blueprints_configmap_name }}" \
|
||||||
|
--from-file="{{ noble_repo_root }}/ansible/.ansible-tmp/authentik-blueprints" \
|
||||||
|
--dry-run=client -o yaml | kubectl apply -f -
|
||||||
|
environment:
|
||||||
|
KUBECONFIG: "{{ noble_kubeconfig }}"
|
||||||
|
when: noble_authentik_blueprints_enabled | default(false) | bool
|
||||||
|
changed_when: true
|
||||||
|
|
||||||
- name: Install Authentik (Helm)
|
- name: Install Authentik (Helm)
|
||||||
ansible.builtin.command:
|
ansible.builtin.command:
|
||||||
argv:
|
argv:
|
||||||
|
|||||||
@@ -25,6 +25,24 @@ global:
|
|||||||
value: "{{ noble_authentik_s3_region }}"
|
value: "{{ noble_authentik_s3_region }}"
|
||||||
- name: AUTHENTIK_STORAGE__S3__ADDRESSING_STYLE
|
- name: AUTHENTIK_STORAGE__S3__ADDRESSING_STYLE
|
||||||
value: "{{ noble_authentik_s3_addressing_style }}"
|
value: "{{ noble_authentik_s3_addressing_style }}"
|
||||||
|
{% if noble_authentik_smtp_host | default('') | trim | length > 0 %}
|
||||||
|
- name: AUTHENTIK_EMAIL__HOST
|
||||||
|
value: {{ noble_authentik_smtp_host | trim | to_json }}
|
||||||
|
- name: AUTHENTIK_EMAIL__PORT
|
||||||
|
value: {{ (noble_authentik_smtp_port | default('587') | string) | to_json }}
|
||||||
|
- name: AUTHENTIK_EMAIL__USERNAME
|
||||||
|
value: {{ noble_authentik_smtp_username | default('') | to_json }}
|
||||||
|
- name: AUTHENTIK_EMAIL__PASSWORD
|
||||||
|
value: {{ noble_authentik_smtp_password | default('') | to_json }}
|
||||||
|
- name: AUTHENTIK_EMAIL__USE_TLS
|
||||||
|
value: {{ (noble_authentik_smtp_use_tls | default('true') | string) | to_json }}
|
||||||
|
- name: AUTHENTIK_EMAIL__USE_SSL
|
||||||
|
value: {{ (noble_authentik_smtp_use_ssl | default('false') | string) | to_json }}
|
||||||
|
- name: AUTHENTIK_EMAIL__TIMEOUT
|
||||||
|
value: {{ (noble_authentik_smtp_timeout | default('30') | string) | to_json }}
|
||||||
|
- name: AUTHENTIK_EMAIL__FROM
|
||||||
|
value: {{ noble_authentik_smtp_from | trim | to_json }}
|
||||||
|
{% endif %}
|
||||||
postgresql:
|
postgresql:
|
||||||
auth:
|
auth:
|
||||||
password: "{{ noble_authentik_postgresql_password }}"
|
password: "{{ noble_authentik_postgresql_password }}"
|
||||||
@@ -46,3 +64,8 @@ server:
|
|||||||
- {{ h }}
|
- {{ h }}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% if noble_authentik_blueprints_enabled | default(false) | bool %}
|
||||||
|
blueprints:
|
||||||
|
configMaps:
|
||||||
|
- {{ noble_authentik_blueprints_configmap_name }}
|
||||||
|
{% endif %}
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
# Noble — directory groups for the **public** hostname Brand (see role README).
|
||||||
|
# Groups are global to the instance; use policies and OAuth scope mappings to scope claims per app.
|
||||||
|
version: 1
|
||||||
|
metadata:
|
||||||
|
name: noble-public-groups
|
||||||
|
labels:
|
||||||
|
blueprints.goauthentik.io/instantiate: "true"
|
||||||
|
entries:
|
||||||
|
{% for group in noble_authentik_blueprint_public_groups | default([]) %}
|
||||||
|
- model: authentik_core.group
|
||||||
|
identifiers:
|
||||||
|
name: "{{ group | trim }}"
|
||||||
|
{% endfor %}
|
||||||
@@ -0,0 +1,101 @@
|
|||||||
|
# Noble — authentication flow for the **lab** hostname Brand: only members of operator groups may continue.
|
||||||
|
# Reuses default identification / password / MFA / login stages; adds a policy on the password stage binding.
|
||||||
|
version: 1
|
||||||
|
metadata:
|
||||||
|
name: noble-lab-operator-authentication
|
||||||
|
labels:
|
||||||
|
blueprints.goauthentik.io/instantiate: "true"
|
||||||
|
entries:
|
||||||
|
- model: authentik_blueprints.metaapplyblueprint
|
||||||
|
attrs:
|
||||||
|
identifiers:
|
||||||
|
name: Default - Password change flow
|
||||||
|
required: false
|
||||||
|
- model: authentik_flows.flow
|
||||||
|
id: flow
|
||||||
|
identifiers:
|
||||||
|
slug: {{ noble_authentik_blueprint_lab_flow_slug | trim | to_json }}
|
||||||
|
attrs:
|
||||||
|
name: Noble lab (operators)
|
||||||
|
title: Noble lab — operators only
|
||||||
|
designation: authentication
|
||||||
|
authentication: none
|
||||||
|
- id: noble-lab-identification-binding
|
||||||
|
model: authentik_flows.flowstagebinding
|
||||||
|
identifiers:
|
||||||
|
order: 10
|
||||||
|
stage: !Find [authentik_stages_identification.identificationstage, [name, default-authentication-identification]]
|
||||||
|
target: !KeyOf flow
|
||||||
|
- id: noble-lab-password-binding
|
||||||
|
model: authentik_flows.flowstagebinding
|
||||||
|
identifiers:
|
||||||
|
order: 20
|
||||||
|
stage: !Find [authentik_stages_password.passwordstage, [name, default-authentication-password]]
|
||||||
|
target: !KeyOf flow
|
||||||
|
attrs:
|
||||||
|
re_evaluate_policies: true
|
||||||
|
- id: noble-lab-authenticator-binding
|
||||||
|
model: authentik_flows.flowstagebinding
|
||||||
|
identifiers:
|
||||||
|
order: 30
|
||||||
|
stage: !Find [authentik_stages_authenticator_validate.authenticatorvalidatestage, [name, default-authentication-mfa-validation]]
|
||||||
|
target: !KeyOf flow
|
||||||
|
- model: authentik_flows.flowstagebinding
|
||||||
|
identifiers:
|
||||||
|
order: 100
|
||||||
|
stage: !Find [authentik_stages_user_login.userloginstage, [name, default-authentication-login]]
|
||||||
|
target: !KeyOf flow
|
||||||
|
- model: authentik_policies_expression.expressionpolicy
|
||||||
|
id: noble-lab-password-optional
|
||||||
|
identifiers:
|
||||||
|
name: noble-lab-password-optional
|
||||||
|
attrs:
|
||||||
|
expression: |
|
||||||
|
flow_plan = request.context.get("flow_plan")
|
||||||
|
if not flow_plan:
|
||||||
|
return True
|
||||||
|
return not hasattr(flow_plan.context.get("pending_user"), "backend")
|
||||||
|
- model: authentik_policies_expression.expressionpolicy
|
||||||
|
id: noble-lab-authenticator-validate-optional
|
||||||
|
identifiers:
|
||||||
|
name: noble-lab-authenticator-validate-optional
|
||||||
|
attrs:
|
||||||
|
expression: |
|
||||||
|
flow_plan = request.context.get("flow_plan")
|
||||||
|
if not flow_plan:
|
||||||
|
return True
|
||||||
|
return not (flow_plan.context.get("auth_method") == "auth_webauthn_pwl")
|
||||||
|
- model: authentik_policies_expression.expressionpolicy
|
||||||
|
id: noble-lab-operators-only
|
||||||
|
identifiers:
|
||||||
|
name: {{ noble_authentik_blueprint_operator_policy_name | trim | to_json }}
|
||||||
|
attrs:
|
||||||
|
expression: |
|
||||||
|
u = context.get("pending_user")
|
||||||
|
if u is None:
|
||||||
|
return False
|
||||||
|
{% for g in noble_authentik_blueprint_lab_operator_groups | default([]) %}
|
||||||
|
if ak_is_group_member(u, name={{ g | trim | to_json }}):
|
||||||
|
return True
|
||||||
|
{% endfor %}
|
||||||
|
ak_message("This login URL is for administrators only. Use the public Authentik hostname instead.")
|
||||||
|
return False
|
||||||
|
- model: authentik_policies.policybinding
|
||||||
|
identifiers:
|
||||||
|
order: 5
|
||||||
|
target: !KeyOf noble-lab-password-binding
|
||||||
|
policy: !KeyOf noble-lab-operators-only
|
||||||
|
- model: authentik_policies.policybinding
|
||||||
|
identifiers:
|
||||||
|
order: 10
|
||||||
|
target: !KeyOf noble-lab-password-binding
|
||||||
|
policy: !KeyOf noble-lab-password-optional
|
||||||
|
attrs:
|
||||||
|
failure_result: true
|
||||||
|
- model: authentik_policies.policybinding
|
||||||
|
identifiers:
|
||||||
|
order: 10
|
||||||
|
target: !KeyOf noble-lab-authenticator-binding
|
||||||
|
policy: !KeyOf noble-lab-authenticator-validate-optional
|
||||||
|
attrs:
|
||||||
|
failure_result: true
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
# Noble — Brands so **Host** selects authentication flow: lab hostname → operator-only flow; extra hosts → default login.
|
||||||
|
version: 1
|
||||||
|
metadata:
|
||||||
|
name: noble-brands-domain-split
|
||||||
|
labels:
|
||||||
|
blueprints.goauthentik.io/instantiate: "true"
|
||||||
|
entries:
|
||||||
|
- model: authentik_brands.brand
|
||||||
|
identifiers:
|
||||||
|
domain: {{ noble_authentik_host | trim | to_json }}
|
||||||
|
attrs:
|
||||||
|
default: false
|
||||||
|
title: {{ noble_authentik_blueprint_lab_brand_title | trim | to_json }}
|
||||||
|
flow_authentication: !Find [authentik_flows.flow, [slug, {{ noble_authentik_blueprint_lab_flow_slug | trim | to_json }}]]
|
||||||
|
flow_invalidation: !Find [authentik_flows.flow, [slug, default-invalidation-flow]]
|
||||||
|
flow_user_settings: !Find [authentik_flows.flow, [slug, default-user-settings-flow]]
|
||||||
|
{% for host in noble_authentik_ingress_extra_hosts | default([]) %}
|
||||||
|
- model: authentik_brands.brand
|
||||||
|
identifiers:
|
||||||
|
domain: {{ host | trim | to_json }}
|
||||||
|
attrs:
|
||||||
|
default: false
|
||||||
|
title: {{ ((noble_authentik_blueprint_public_brand_title_prefix | default('Noble public')) ~ ' (' ~ (host | trim) ~ ')') | to_json }}
|
||||||
|
flow_authentication: !Find [authentik_flows.flow, [slug, default-authentication-flow]]
|
||||||
|
flow_invalidation: !Find [authentik_flows.flow, [slug, default-invalidation-flow]]
|
||||||
|
flow_user_settings: !Find [authentik_flows.flow, [slug, default-user-settings-flow]]
|
||||||
|
{% endfor %}
|
||||||
@@ -13,6 +13,8 @@
|
|||||||
#
|
#
|
||||||
# **Media / uploads:** **S3** (same endpoint/credentials pattern as **Velero** — see **ansible/roles/noble_authentik** and **.env.sample**).
|
# **Media / uploads:** **S3** (same endpoint/credentials pattern as **Velero** — see **ansible/roles/noble_authentik** and **.env.sample**).
|
||||||
# Ansible sets **`AUTHENTIK_STORAGE__BACKEND=s3`** in **`authentik-extra-values.yaml.j2`**; use a **dedicated** media bucket, not the Velero backup bucket.
|
# Ansible sets **`AUTHENTIK_STORAGE__BACKEND=s3`** in **`authentik-extra-values.yaml.j2`**; use a **dedicated** media bucket, not the Velero backup bucket.
|
||||||
|
# **SMTP:** optional — set **`NOBLE_AUTHENTIK_SMTP_HOST`** + **`NOBLE_AUTHENTIK_SMTP_FROM`** in repo **`.env`** so Ansible injects **`AUTHENTIK_EMAIL__*`** into Helm **`global.env`** (see role README).
|
||||||
|
# **Blueprints:** optional **`blueprints.configMaps`** is merged by Ansible when **`noble_authentik_blueprints_enabled`** is true — see **`ansible/roles/noble_authentik/README.md`**.
|
||||||
|
|
||||||
postgresql:
|
postgresql:
|
||||||
enabled: true
|
enabled: true
|
||||||
|
|||||||
@@ -26,11 +26,30 @@ VERSITYGW_WEBUI_PORT=8080
|
|||||||
# VGW_WEBUI_GATEWAYS=https://s3.example.com
|
# VGW_WEBUI_GATEWAYS=https://s3.example.com
|
||||||
VGW_WEBUI_GATEWAYS=
|
VGW_WEBUI_GATEWAYS=
|
||||||
|
|
||||||
# Public origin of the **WebUI** page (Pangolin → :8080), e.g. https://s3-ui.example.com
|
# Public origin of the **browser app** that calls the S3 API (no path, no trailing slash).
|
||||||
# Required when UI and API are on different hosts so the browser can call the API (CORS).
|
# Use this when the UI is on a different hostname than the API — e.g. third-party S3 consoles,
|
||||||
|
# or the built-in WebUI behind Pangolin on another host than :10000.
|
||||||
|
# Example: VGW_CORS_ALLOW_ORIGIN=https://s3-ui.pcenicni.dev
|
||||||
|
#
|
||||||
|
# VersityGW maps the browser’s preflight Access-Control-Request-Headers into
|
||||||
|
# Access-Control-Allow-Headers (Authorization, X-Amz-Date, X-Amz-Content-Sha256, Content-Type, …)
|
||||||
|
# when there is **no** per-bucket CORS configuration. You do not set those headers separately here.
|
||||||
|
#
|
||||||
|
# If you used PutBucketCors on a bucket, that config replaces this fallback for that bucket: add
|
||||||
|
# the same Origin and AllowedHeader entries (or *) there, or delete bucket CORS to rely on this.
|
||||||
# VGW_CORS_ALLOW_ORIGIN=https://s3-ui.example.com
|
# VGW_CORS_ALLOW_ORIGIN=https://s3-ui.example.com
|
||||||
VGW_CORS_ALLOW_ORIGIN=
|
VGW_CORS_ALLOW_ORIGIN=
|
||||||
|
|
||||||
|
# --- Pangolin (edge) vs Versity CORS ---
|
||||||
|
# If VGW_CORS_ALLOW_ORIGIN is correct but the browser still says CORS failed, the edge often
|
||||||
|
# never returns Versity’s Access-Control-* headers: Pangolin can answer OPTIONS / block preflight
|
||||||
|
# before Newt reaches :10000. S3 clients send OPTIONS without SigV4 auth; Pangolin SSO or
|
||||||
|
# “authorization” on the HTTP resource can reject that (see https://github.com/fosrl/pangolin/issues/2369 ).
|
||||||
|
# Mitigations: make the **S3 API** hostname resource public (no Pangolin auth on that resource),
|
||||||
|
# or add a rule that allows OPTIONS to pass through when Pangolin supports method-based rules;
|
||||||
|
# confirm with: curl -sv -X OPTIONS -H "Origin: https://your-s3-ui" -H "Access-Control-Request-Method: PUT" \
|
||||||
|
# -H "Access-Control-Request-Headers: authorization,content-type" "https://your-s3-api-host/" 2>&1 | head -40
|
||||||
|
|
||||||
# NFS: object metadata defaults to xattrs; most NFS mounts need sidecar mode
|
# NFS: object metadata defaults to xattrs; most NFS mounts need sidecar mode
|
||||||
# (compose.yaml uses --sidecar /data/sidecar). Create the host path, e.g.
|
# (compose.yaml uses --sidecar /data/sidecar). Create the host path, e.g.
|
||||||
# mkdir -p /mnt/nfs/versity/sidecar
|
# mkdir -p /mnt/nfs/versity/sidecar
|
||||||
|
|||||||
@@ -26,7 +26,8 @@ services:
|
|||||||
# Public base URL of the *S3 API* only (Pangolin → :10000). Not the WebUI hostname.
|
# Public base URL of the *S3 API* only (Pangolin → :10000). Not the WebUI hostname.
|
||||||
# No trailing slash. If this points at the UI URL, bucket ops return 404/wrong host.
|
# No trailing slash. If this points at the UI URL, bucket ops return 404/wrong host.
|
||||||
VGW_WEBUI_GATEWAYS: ${VGW_WEBUI_GATEWAYS}
|
VGW_WEBUI_GATEWAYS: ${VGW_WEBUI_GATEWAYS}
|
||||||
# Browser Origin when WebUI and API use different HTTPS hostnames (see wiki / WebGUI CORS).
|
# Browser Origin for cross-host S3 from the UI (maps to --cors-allow-origin). See .env.sample
|
||||||
|
# for third-party consoles vs bucket PutBucketCors overrides.
|
||||||
VGW_CORS_ALLOW_ORIGIN: ${VGW_CORS_ALLOW_ORIGIN}
|
VGW_CORS_ALLOW_ORIGIN: ${VGW_CORS_ALLOW_ORIGIN}
|
||||||
ports:
|
ports:
|
||||||
- "${VERSITYGW_PORT:-10000}:10000"
|
- "${VERSITYGW_PORT:-10000}:10000"
|
||||||
|
|||||||
Reference in New Issue
Block a user