railiance-cluster/workplans/RCLUSTER-WP-0019-k3s-admin-kubeconfig-mode.md
codex 48de6d9ee0
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
RCLUSTER-WP-0019-T03: attended apply on railiance01 done
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 605711@bnt-lap001
Assistant-Session: 1f5e2256-181f-49ed-b7b1-a1c34bf37a61
2026-10-20 22:42:44 +02:00

3.2 KiB

id type title domain repo status owner topic_slug created updated flavor depends_on related state_hub_workstream_id
RCLUSTER-WP-0019 workplan Restrict k3s admin kubeconfig to root (write-kubeconfig-mode 600) financials railiance-cluster active claude railiance 2026-10-20 2026-10-20 implementation
CUST-WP-0073
9d469414-c8c5-54a8-97e3-0b11bec383a7

Owner source work for CUST-WP-0073-T02 (railiance-cluster part: k3s install config). k3s on railiance01 runs with --write-kubeconfig-mode=644, so the system:masters kubeconfig at /etc/rancher/k3s/k3s.yaml is world-readable. Reviewed inputs: the-custodian docs/changes/CUST-WP-0073/credential-boundary-r1/ cluster-bootstrap.patch and existing-k3s-host-r1/ (read-only observation: one effective mode-644 flag in the root-owned unit, no drop-ins, no config.yaml, unit SHA256 b5398c38...). This repo is not auto-applied (no GitOps/CI deploy); nothing changes on a host until an attended operator runs a playbook.

Known consumer to migrate: railiance-platform scripts/application_backup_credentials.py reads the admin kubeconfig path and must run as root (or use a scoped identity) after the change.

Installer: mode 600, no admin kubeconfig export

id: RCLUSTER-WP-0019-T01
status: done
priority: high
assignee: claude
state_hub_task_id: "c456e31d-ecac-55b3-8055-26fc8c1bc5e7"

ansible/bootstrap.yml installs with --write-kubeconfig-mode=600, no longer fetches the admin kubeconfig to the controller, and enforces root:root 0600 on the file. Fresh installs only: the creates guard leaves existing hosts alone.

Existing-host playbook (source, offline-validated)

id: RCLUSTER-WP-0019-T02
status: done
priority: high
assignee: claude
state_hub_task_id: "f25e57c9-523c-5c76-9b02-ed37ecd3598b"

ansible/k3s-kubeconfig-mode.yml: pinned preimage/candidate hashes, refusal on drift/drop-ins/pending reload/foreign config.yaml, root-only unit backup, two-byte flag rewrite plus config.yaml write-kubeconfig-mode: "0600", daemon-reload + restart, /readyz + node Ready + root:root 0600 verification, check/diff support with unit content suppressed, and a rollback action. Validated offline only (syntax-check, ansible-lint production profile, local transform test on a synthetic unit). No host connection.

Attended apply on railiance01

id: RCLUSTER-WP-0019-T03
status: done
priority: high
state_hub_task_id: "012fb36b-2b19-51ef-ac0a-22a9ffd3e6a8"

Done 2026-10-20 (attended, founder present). Applied on railiance01: admin kubeconfig root:root 0600, API ready, node Ready; unit backup retained root-only. Also found registries.yaml 0644 with a registry login; restricted to 0600 and persisted (36f733c). Evidence: the-custodian docs/evidence/2026-10-20-railiance01-cutover-steps-2-4.md.

ansible-playbook ansible/k3s-kubeconfig-mode.yml -e target=<railiance01 inventory host> --check --diff
ansible-playbook ansible/k3s-kubeconfig-mode.yml -e target=<railiance01 inventory host> --diff

Retain sanitized output (mode/owner, hashes, readyz) as evidence for CUST-WP-0073-T02. Rollback: rerun with -e k3s_kubeconfig_mode_action=rollback -e k3s_unit_backup=/root/k3s-kubeconfig-mode-backup/k3s.service.b5398c385430.