Files
computer-playbook/roles/web-app-wordpress/tasks/addons/wp-discourse-stack-host.yml
kevinveenbirkenbachandClaude Opus 5 b3ce43a596 fix(security): require no_log on every task that carries a credential
At -vvv Ansible prints each module argument and result, so a password in
a command line, a request body, a header or a fact lands in the deploy
log. Nothing enforced masking outside the MCP task files, and no check
looked at parents at all.

A new lint, test_credential_tasks_are_masked, finds tasks whose printed
parts (module arguments, environment, loop) reference an identifier ending
in password, secret, token, api_key or private_key, or
secrets.credentials. A task passes when it or an enclosing block sets
no_log, when every file that pulls it in does so through include_tasks
with apply.no_log or import_tasks with no_log (transitively), when the
secret only reaches a parameter the module masks itself, or when the
module masks its values. no_log on an include_tasks task itself does not
count, because it does not reach the included tasks. The rule can be
suppressed per task with `# nocheck: credential-masking`, now listed in
the suppression catalog, and the lint tests its parent and suppression
logic on synthetic cases.

It found 39 unmasked tasks in 19 roles, all real: join tokens, client
secrets, API tokens in Cloudflare headers, database passwords in
command lines, the ChatGPT bot login body and more. Each now sets
no_log from MASK_CREDENTIALS_IN_LOGS. The sys-dns-hetzner-rdns alias
hetzner_no_log, which only restated that switch, is gone.

Not covered yet: template and copy tasks whose rendered file carries a
secret print it as a diff under --diff.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-11 21:52:18 +02:00

32 lines
1.4 KiB
YAML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
- name: ➕ Add /var/www/discourse to Git safe.directory
ansible.builtin.shell: > # nocheck: container-exec-resolver discourse is a launcher-managed container named literally in both modes
container exec {{ WORDPRESS_DISCOURSE_CONTAINER_ADDRESS }}
git config --global --add safe.directory /var/www/discourse
changed_when: false
- name: 🚫 Revoke old WP Discourse API keys via Rails
ansible.builtin.command:
argv:
- container
- exec
- -i
- "{{ WORDPRESS_DISCOURSE_CONTAINER_ADDRESS }}" # nocheck: container-exec-resolver discourse is a launcher-managed container named literally in both modes
- bash
- -lc
- "cd /var/www/discourse && script/rails runner -"
stdin: "{{ lookup('file', 'ruby/revoke_wp_discourse_api_keys.rb') }}"
changed_when: false
failed_when: false
- name: ⚙️ Generate new WP Discourse API key via Rake task
ansible.builtin.shell: > # nocheck: container-exec-resolver discourse is a launcher-managed container named literally in both modes
container exec {{ WORDPRESS_DISCOURSE_CONTAINER_ADDRESS }}
bash -lc "cd /var/www/discourse && bin/rake api_key:create_master['WP Discourse Integration']"
register: discourse_generated_api_key
- name: 💾 Store the new WP Discourse API key in a fact
no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}"
set_fact:
vault_discourse_api_key: "{{ discourse_generated_api_key.stdout | trim }}"