Skip to content

Migration note: Migrated from ADR-0046 on 2026-05-02 per ADR-0047. Original file retained at docs/adr/0046-it-ot-ansible-service-account-separation.md with deprecation banner.

IAM-0004: OT Ansible Service Account Separation (ansible-ot-svc-account)

Sources

  • ADR-0046: Separate Ansible Service Accounts per IT/OT Zone (IEC 62443) (2026-05-02)
Field Value
ID IAM-0004
Date 2026-05-02
Status Accepted
Author Ben Peries
Class security/IAM

Status

Accepted — 2026-05-02

Context

IAM-0003 established a single ansible-svc-account service account for all managed nodes. This was appropriate when only IT nodes (caneast-site1-node2-5) were under Ansible management.

A 2026-05-02 zone classification audit confirmed that caneast-site1-mqtt1 (Pi Zero 2 W, Mosquitto broker) is classified as an OT node under the IEC 62443 zone-and-conduit model. It appears in ansible/inventories/ot/hosts.yml (mqtt_brokers group) and in the AWX caneast-ot inventory. Using the same Ansible service account across IT and OT zones collapses the zone boundary that IEC 62443 requires.

An audit finding was also identified: ot/hosts.yml had ansible_user=operator and ansible_port=22, both deviating from platform standards and creating audit trail confusion.

Architect review (C.10) considered collapsing OT into the IT Ansible account for convenience (Option B) but this was rejected by Ben on IEC 62443 grounds. The zone-and-conduit separation is a load-bearing security control, not organisational convention.

CISO review approved the three-phase plan described below.

Decision

Mint a dedicated ansible-ot-svc-account service account for OT-zone Ansible automation. The IT account (ansible-svc-account) must never have access to OT nodes. The OT account (ansible-ot-svc-account) must never have access to IT nodes.

Account Specification: ansible-ot-svc-account

  • Username: ansible-ot-svc-account
  • UID: 1500 (distinct from IT ansible-svc-account, which uses UID REDACTED)
  • SSH key: Ed25519, comment ansible-ot-svc-account@archon-platform-phase1
  • SSH port: 2222 (consistent with IT platform standard)
  • Sudo: none on IT nodes; limited scope on OT nodes (Phase 2, to be defined)
  • Groups: default only (no docker, no sudo cross-zone)
  • Home: /home/ansible-ot-svc-account

Secret Storage

Infisical path: /archon-platform/prod/ANSIBSVCOPS_OT_SSH_PRIVATE_KEY Never commit private key material to any repository.

Zone Isolation Rules

Rule IT nodes (caneast-site1-node2-5) OT nodes (caneast-site1-mqtt1)
ansible-svc-account (IT) Full sudo Not present
ansible-ot-svc-account (OT) Not present Phase 2: limited sudo
operator (personal) Interactive only Interactive only (Phase 1 transitional)

Three-Phase Implementation Plan

Phase 1 (Sprint 4, WI-382) — Complete

  • Keypair generated on CanEast AI Node (accepted limitation, see below)
  • ansible-ot-svc-account user created on caneast-site1-mqtt1: UID REDACTED, Ed25519 auth, zero sudoers
  • sshd on caneast-site1-mqtt1 configured to listen on port REDACTED alongside port 22
  • node_exporter deployed via ansible/playbooks/ot/node-exporter.yml (run as operator with sudo; Phase 1 transitional)
  • ot/hosts.yml updated: ansible_user=ansible-ot-svc-account, ansible_port=2222 (audit finding remediated)
  • Private key stored in Infisical

Phase 1 limitation: keypair generated on CanEast AI Node (IT zone workstation). This is a known accepted deviation from the full zone model. Phase 3 regenerates the keypair on the OT jump host.

Phase 2 (Sprint 5+, pending WI) — OT Ansible Migration to archon-apps

  • Migrate ansible/inventories/ot/ and ansible/playbooks/ot/ from archon-platform to archon-apps (per IAM-0002, which assigns OT application code to archon-apps).
  • Static analysis gate: ot/site.yml must have zero IT role dependencies before migration proceeds.
  • Add limited sudoers for ansible-ot-svc-account on caneast-site1-mqtt1 for specific task paths (node_exporter install, systemd management).
  • Wire caneast-site1-mqtt1:[REDACTED] into Prometheus additionalScrapeConfigs.

Phase 3 (post-OPNsense ICT activation) — Full Zone Separation

  • Deploy AWX execution context dedicated to OT inventory (separate execution environment).
  • Deploy caneast-site1-jmp1 OT jump host with OPNsense conduit rules.
  • Regenerate ansible-ot-svc-account keypair on caneast-site1-jmp1 (key never leaves OT zone).
  • Enable ansible_ssh_common_args: -o ProxyJump=ansible-svc-account@caneast-site1-jmp1 in ot/hosts.yml.
  • Retire the CanEast AI Node Phase 1 keypair.

CISO Conditions

All five conditions must be satisfied before the Phase 2 gate passes:

  1. UID REDACTED assigned to ansible-ot-svc-account on all OT nodes (consistent, not shared with IT).
  2. Zero cross-zone sudoers: ansible-ot-svc-account has no sudo on IT nodes; ansible-svc-account has no access to OT nodes.
  3. Key rotation cadence documented and enforced: annual rotation or immediate rotation on role change (person with key access leaves team or changes role).
  4. Phase 2 static analysis gate: ot/site.yml must have no IT role imports or dependencies before archon-apps migration begins.
  5. Phase 1 limitation acknowledged in writing (this ADR) that the keypair was generated on an IT-zone workstation and will be replaced in Phase 3.

Key Rotation Cadence

  • Rotation trigger: annual, or on any of: personnel change with key access, suspected key compromise, Phase 3 migration.
  • Rotation procedure: generate new Ed25519 keypair on caneast-site1-jmp1 (Phase 3+) or CanEast AI Node (Phase 1-2), update Infisical, update authorized_keys on all OT nodes, retire old key.
  • Rotation must be documented in an ADR addendum or post-change note.

Alternatives Considered

Collapse OT into the IT ansible-svc-account account (Option B) — Rejected by Ben on IEC 62443 grounds. Zone-and-conduit separation is a load-bearing security control, not organisational convention. A shared account collapses the zone boundary.

Per-playbook SSH keys — More granular but harder to manage at scale; inconsistent with platform service account pattern.

Consequences

  • OT nodes (caneast-site1-mqtt1+) must never have the IT ansible-svc-account account provisioned
  • IT nodes must never have the OT ansible-ot-svc-account account provisioned
  • AWX caneast-ot inventory uses ansible-ot-svc-account credentials exclusively
  • Phase 2 migration of OT Ansible to archon-apps is gated on all five CISO conditions
  • Phase 1 limitation (key generated on IT workstation) is an accepted, documented deviation

References

  • IAM-0002: IT/OT zone separation policy
  • IAM-0003: IT Ansible service account pattern (ansible-svc-account); see addendum 2026-05-02
  • OT-0001: OT zone classification and IEC 62443 principles
  • WI-382: Phase 1 implementation
  • WI-380: Phase 1 planning and CISO gate verification