Files
computer-playbook/roles/web-app-n8n/templates/playwright.env.j2
kevinveenbirkenbachandClaude Opus 5 43ca7f73ae feat(n8n): provision the managed openAiApi credential against the gateway
AI Agent nodes read their endpoint from a stored credential, not from the
environment, so the gateway base URL and this role's virtual key have to land in
n8n's credential store. files/provision_ai.py logs in as the owner and upserts an
openAiApi credential under the deterministic name infinito:litellm.

The write goes through the internal /rest routes because that is the only place
the pinned 1.95.3 exposes credential creation: the public /api/v1 key this role
already mints for MCP carries workflow scopes and cannot create a credential.
That is why this is a second script rather than another call inside
provision_mcp.py.

n8n encrypts credential data at rest and never returns it, so there is nothing
to compare against and the managed credential is overwritten rather than
reconciled. The script prints CHANGED or OK so the task can report change state
without pretending to have diffed a value it cannot read.

env.j2 sets only N8N_AI_ENABLED. An earlier revision of this work templated
N8N_INSTANCE_AI_MODEL_URL, which does not exist in 1.95.3 -- it was invented
rather than measured, and has been removed along with the requirement table row
that repeated it. The one real AI environment variable in that release,
N8N_AI_ASSISTANT_BASE_URL, expects n8n's own assistant service rather than an
OpenAI-compatible endpoint, so the credential store is the only usable surface.

vars/main.yml also carries N8N_MCP_CREDENTIAL_NAME. It belongs to the MCP work
rather than to this change, but a file cannot be split across commits and this
order is the safe one: the MCP tasks land later and find the constant already
present, where the reverse would reference a variable that does not exist yet.

Verified: the spec runs rather than skipping -- it appears in the variant-2
JUnit as "administrator: the managed openAiApi credential answers a prompt
through the in-cluster gateway".
Not verified: I confirmed it executed, not its verdict. The owner-cookie login
is also unexercised on an sso-only variant, and because the credential is
rewritten every run, an operator's manual edit is replaced without notice.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-24 13:44:34 +02:00

43 lines
1.7 KiB
Bash

ADMIN_EMAIL={{ lookup('users', 'administrator').email | dotenv_quote }}
ADMIN_PASSWORD={{ lookup('users', 'administrator').password | dotenv_quote }}
ADMIN_USERNAME={{ lookup('users', 'administrator').username | dotenv_quote }}
BIBER_EMAIL={{ lookup('users', 'biber').email | dotenv_quote }}
BIBER_PASSWORD={{ lookup('users', 'biber').password | dotenv_quote }}
BIBER_USERNAME={{ lookup('users', 'biber').username | dotenv_quote }}
CANONICAL_DOMAIN={{ lookup('domain', application_id) | dotenv_quote }}
# nocheck: playwright-service-gate — covered by sys-svc-mail integration tests, not the persona surface
EMAIL_SERVICE_ENABLED={{ lookup('config', application_id, 'services.email.enabled') | string | lower }}
LITELLM_SERVICE_ENABLED={{ N8N_LITELLM_ENABLED | string | lower }}
LOGOUT_SERVICE_ENABLED={{ lookup('config', application_id, 'services.logout.enabled') | string | lower }}
MATOMO_BASE_URL={{ lookup('tls', 'web-app-matomo', 'url.base') | dotenv_quote }}
MATOMO_SERVICE_ENABLED={{ lookup('config', application_id, 'services.matomo.enabled') | string | lower }}
MCP_ENDPOINT_PATH={{ lookup('config', application_id, 'mcp.endpoint.path') | dotenv_quote }}
MCP_SERVICE_ENABLED={{ N8N_MCP_ENABLED | string | lower }}
N8N_BASE_URL={{ lookup('tls', application_id, 'url.base') | dotenv_quote }}
N8N_LITELLM_BASE_URL={{ N8N_LITELLM_BASE_URL | dotenv_quote }}
N8N_LITELLM_CREDENTIAL_NAME={{ N8N_LITELLM_CREDENTIAL_NAME | dotenv_quote }}
N8N_LITELLM_MODEL={{ LITELLM_CHAT_MODEL | dotenv_quote }}
N8N_OWNER_PASSWORD={{ N8N_OWNER_PASSWORD | dotenv_quote }}
OIDC_ISSUER_URL={{ OIDC.CLIENT.ISSUER_URL | dotenv_quote }}
SSO_SERVICE_ENABLED={{ N8N_SSO_ENABLED | string | lower }}