railiance-infra/ansible/playbooks/verify.yaml
codex 40e295e3bd
All checks were successful
CI Smoke / source-contract (push) Successful in 8s
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Make S1 handoff read-only by default
Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a02994-7685-7940-bf34-3555b8256018
2026-08-23 12:41:23 +02:00

84 lines
2.9 KiB
YAML

---
# verify.yaml — Read-only S1 baseline verification and local TAP collection.
#
# This playbook must not install, template, enable, restart, or otherwise
# mutate a managed host. scripts/handoff_contract.py enforces the allowed
# module and command surface before scripts/s1_handoff.py contacts a host.
# Use verify-refresh.yaml only after reviewing and approving host changes.
- name: Verify the installed S1 baseline without changing the host
hosts: all
become: true
gather_facts: false
vars_files:
- ../inventory/group_vars/all.yaml
vars:
goss_bin: /usr/local/bin/goss
goss_config: /etc/goss/baseline.yaml
expected_goss_baseline: >-
{{ lookup('ansible.builtin.template',
playbook_dir ~ '/../../goss/baseline.yaml.j2',
keep_trailing_newline=true) }}
expected_goss_sha256: "{{ expected_goss_baseline | hash('sha256') }}"
report_stamp: "{{ now(utc=true, fmt='%Y%m%dT%H%M%SZ') }}"
tasks:
- name: Inspect the installed Goss executable
ansible.builtin.stat:
path: "{{ goss_bin }}"
register: installed_goss
- name: Inspect the installed baseline digest
ansible.builtin.stat:
path: "{{ goss_config }}"
checksum_algorithm: sha256
register: installed_baseline
- name: Require the exact source-rendered verification surface
ansible.builtin.assert:
that:
- installed_goss.stat.exists | default(false)
- installed_goss.stat.executable | default(false)
- installed_baseline.stat.exists | default(false)
- installed_baseline.stat.checksum | default('') == expected_goss_sha256
fail_msg: >-
{{ inventory_hostname }} has no usable Goss surface or its baseline is
stale. Review changes, then run verify-refresh for this host before
retrying the read-only handoff gate.
- name: Run the installed baseline assertions
ansible.builtin.command:
argv:
- "{{ goss_bin }}"
- -g
- "{{ goss_config }}"
- validate
- --format
- tap
register: goss_result
changed_when: false
failed_when: false
- name: Ensure the controller reports directory exists
ansible.builtin.file:
path: "{{ playbook_dir }}/../../reports"
state: directory
mode: "0755"
delegate_to: localhost
become: false
- name: Record TAP evidence on the controller
ansible.builtin.copy:
content: "{{ goss_result.stdout }}\n"
dest: >-
{{ playbook_dir }}/../../reports/goss-{{ inventory_hostname }}-{{ report_stamp }}.tap
mode: "0644"
delegate_to: localhost
become: false
changed_when: false
- name: Fail closed on a baseline assertion failure
ansible.builtin.assert:
that:
- goss_result.rc == 0
fail_msg: "Goss baseline failed on {{ inventory_hostname }}"