feat(secrets): webhook URL and git tokens sealed; run output masks its secrets (#5037)
#5037 "Secrets at rest and in run output: webhook URL and git token encrypted, askpass via env, secret values scrubbed from logs". - webhook.url joins SECRET_KEYS; existing values are sealed at startup by migrate_plaintext_secrets. Settings -> Notifications no longer echoes the URL: it names the saved host, keeps it when left blank, and has a Remove box. - Git source http_token is sealed inside ansible.sources on save and at startup, opened in get_sources, and counted by the undecryptable-secrets scan as ansible.sources[<name>].http_token. - The askpass script holds no token: git runs it with STEWARD_GIT_TOKEN in its environment and printf prints it as data. - The executor masks every secret the run is handed (become/vault passwords, bootstrap passwords, sensitive run vars, and the per-host agent tokens the host_agent plugin now passes as redact) in each line before it is broadcast, logged or stored. - Bundled "Write agent config" tasks are no_log; a test fails if any bundled task templating steward_token lacks it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -56,10 +56,18 @@
|
||||
<h2 class="section-title" style="margin-bottom:1.25rem;">Webhook</h2>
|
||||
|
||||
<div class="form-group">
|
||||
<label>URL <span style="color:var(--text-muted);font-size:0.8rem;">(leave blank to disable)</span></label>
|
||||
<input type="text" name="webhook.url" value="{{ settings['webhook.url'] }}"
|
||||
placeholder="https://discord.com/api/webhooks/...">
|
||||
<label>URL {% if webhook_host %}<span style="color:var(--text-muted);font-size:0.8rem;">(saved for {{ webhook_host }}; leave blank to keep it)</span>{% endif %}</label>
|
||||
<input type="password" name="webhook.url" autocomplete="off"
|
||||
placeholder="{% if webhook_host %}enter a new URL to replace{% else %}https://discord.com/api/webhooks/...{% endif %}">
|
||||
<p style="font-size:0.75rem;color:var(--text-muted);margin-top:0.2rem;">
|
||||
Stored encrypted and never shown again: a webhook URL usually holds its own token.</p>
|
||||
</div>
|
||||
{% if webhook_host %}
|
||||
<div class="form-group" style="display:flex;align-items:center;gap:0.5rem;">
|
||||
<input type="checkbox" name="webhook.remove" id="webhook-remove">
|
||||
<label for="webhook-remove" style="margin:0;">Remove the webhook</label>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="form-group">
|
||||
<label>Payload template <span style="color:var(--text-muted);font-size:0.8rem;">(Jinja2, must produce valid JSON)</span></label>
|
||||
|
||||
Reference in New Issue
Block a user