2. Requirements
2. Requirements
← Previous: 1. Introduction | Index | Next: 3. Architecture →
2.1 Problem Restatement
The platform requires host access that:
- Identifies every human session with a named Entra identity, protected by MFA, with no shared or standing credentials.
- Authorizes each person to a defined tier per environment — including a tier that can deploy but cannot write, and a tier that can
sudofor routine administration but cannot switch to any other user. - Elevates to full root only just-in-time, for a bounded window, with justification and evidence.
- Decommissions a person with a single identity-provider action, with bounded time to effect on every host, and with evidence.
- Is managed centrally in Git and Entra — never by hand on a host, never by direct user→role assignment.
- Uses existing tooling — Azure Arc, Entra ID, PIM, Terraform, Ansible, Sentinel — and introduces no access broker.
2.2 Design Goals
2.2.1 Primary Goals
| ID | Goal | Rationale |
|---|---|---|
| G-1 | Single login path — Arc SSH with Entra is the only way a human reaches a shell | Attribution, MFA, and revocation come from one place |
| G-2 | Entra groups are the sole source of authorization | One edit grants or removes access everywhere; matches RFC-IAM-0001's ceiling and STD-IDENT-001 |
| G-3 | Enforceable tiers — Admin, Operator, Editor, Deployer, Viewer — per machine class | "Deploy but cannot write" must be physically true |
| G-4 | Just-in-time root via PIM, never standing | Bounds the exposure window of the most powerful access |
| G-5 | No human ever holds Docker socket access | Docker access is root access; the deploy action mediates it |
| G-6 | Automatic decommissioning with time bounds | Removes the "hope nothing was missed" step |
| G-7 | Declarative delivery — Terraform for Azure, Ansible for hosts, Entra for membership | Reviewable, reproducible, drift-detectable |
| G-8 | Evidence in Sentinel for logins, elevations, privileged commands, deploys, drift and break-glass | Audit without reconstruction |
2.2.2 Secondary Goals
| ID | Goal | Rationale |
|---|---|---|
| G-9 | Minimal friction for routine work — no repeated prompts for the standing tier | Security that impedes daily work gets bypassed |
| G-10 | Additive rollout; no disruption; shared key removed last | The team must keep shipping throughout |
| G-11 | Preserve automation identities untouched | Ansible/Terraform/k8s join keys are out of scope and load-bearing |
2.3 Non-Goals
| Non-Goal | Rationale / Covered By |
|---|---|
| Full keystroke session recording for every shell | Not provided by Arc; privileged-command recording and file-change evidence are provided instead (Section 10); full recording is an Evolution option |
| Web-application SSO | RFC-IAM-0001 |
| Machine / workload identity | RFC-WORKLOAD-IDENTITY-0001 |
| Windows host access (RDP) | Separate design; hosts listed as out of scope |
| Kubernetes deploys by humans | GitOps (ArgoCD); no human deploy tier on k8s or PVE hosts |
| Secret storage and rotation mechanics | RFC-SECOPS-0001; this RFC only lists which secrets a leaver could read |
| Network-level access control | RFC-TENANT-SECURITY |
2.4 Architectural Invariants
These rules MUST always hold. Each is falsifiable: violation is observable and, where noted, machine-detectable.
Invariant 1 — Single Human Login Path
Interactive human access to a Linux host MUST be established only through Azure Arc SSH authenticated by Microsoft Entra ID (AADSSHLoginForLinux). Human accounts MUST NOT have a password and MUST NOT have any authorized_keys path.
Detection: any human account with a password hash or an authorized_keys file; any successful sshd publickey or password authentication for a human account.
Why: a second door defeats attribution, MFA and revocation at once.
Invariant 2 — Group-Derived Authorization Only
Every Azure role assignment used for host access MUST be to an Entra group, declared in Terraform. Direct user→role assignments MUST NOT exist. On-host privilege (Linux group membership) MUST derive only from Entra group membership via the synchronisation agent.
Detection: any role assignment whose principal is a user; any tier group member on a host who is not a member of the corresponding Entra group. Why: STD-IDENT-001 §A; a hand-made grant is invisible to review and survives a leaver.
Invariant 3 — No Standing Root
Virtual Machine Administrator Login MUST be assigned only as a PIM-eligible assignment. No human MUST hold it as an active, permanent assignment. Activations MUST require MFA and a justification and MUST NOT exceed 4 hours; activations on the prod class MUST require an approver.
Detection: any active (non-eligible) Administrator Login assignment to a human or human group; any activation exceeding the policy. Why: bounds the blast radius of the most powerful capability (RFC-PAM-0001 G-6 carried forward).
Invariant 4 — No Human in the Docker Group
No human account MUST be a member of the docker group or otherwise able to reach the Docker socket directly. Container operations for humans MUST be mediated by the deploy action running as the deploy service account.
Detection: getent group docker lists any human account; any human process with the socket open.
Why: Docker socket access is root-equivalent; this invariant is what makes the Deployer tier real.
Invariant 5 — Operator Cannot Become Anyone Else
The Operator tier's sudo policy MUST be a positive allow-list executed as root only (Runas restricted to root). It MUST NOT include su, any shell, any interactive editor, or any command that edits sudoers. su MUST be disabled for all accounts via pam_wheel with an empty wheel group.
Detection: a successful su by any account; a successful sudo -u <non-root> by an Operator; any allow-list entry that is a shell or editor.
Why: negation in sudoers ("ALL except su") is bypassable and MUST NOT be used (Section 12).
Invariant 6 — Editor Requires Admin Eligibility
The Editor tier MUST be granted only to a person who is PIM-eligible for Admin on the same machine class, unless the deploy definitions (compose files) on that class are root-owned and Git-controlled.
Detection: an Editor-group member on a class who is not in pn-host-admin.
Why: an Editor can modify what the deploy action runs and thereby reach root; the tier is honest only for people already trusted with root.
Invariant 7 — Single-Action Decommissioning
Removal of a person from the relevant Entra groups (or disabling their account) MUST be the only action required to revoke all of their human host access. No per-host manual step MUST be required.
Detection: a decommissioning runbook step that touches a host by hand; any host where a removed person retains group membership or an unlocked account beyond the bound in Invariant 8. Why: Problem 3.
Invariant 8 — Bounded Time to Effect
After Entra removal: new logins MUST be denied immediately; active sessions MUST be terminated and on-host privilege removed within 5 minutes; the account MUST be locked within 5 minutes and removed (home archived) after 30 days.
Detection: the group-sync heartbeat reports a host out of agreement with Entra for longer than one cycle. Why: a guarantee that can be measured, not a hope.
Invariant 9 — No Human Account Without Live Membership
No human account MUST exist unlocked on a host without a corresponding live Entra membership in at least one tier group for that host's class.
Detection: the heartbeat's "accounts present vs. Entra membership" comparison. Why: closes STD-IDENT-001's declared host-layer stale-user gap.
Invariant 10 — Fail-Safe Synchronisation
When the synchronisation agent cannot obtain an authoritative answer from Entra, it MUST make no changes. It MUST NOT remove access on error.
Detection: an access removal logged without a corresponding authoritative "not a member" result. Why: Azure independently denies logins; a wrongful removal is worse than a delay.
Invariant 11 — Declared, Logged Break-Glass
Each host MUST have exactly one break-glass root key, stored in Azure Key Vault. Its use MUST raise an alert and MUST be followed by a retrospective incident (STD-IDENT-001 §D). It MUST be rotated when any person who could retrieve it leaves.
Detection: a root publickey login with no alert; more than one root key on a host; a leaver with Key Vault access without a subsequent rotation.
Why: break-glass is legitimate; silent break-glass is the OVH anti-pattern STD-IDENT-001 forbids.
Invariant 12 — Evidence Ships Off-Host
Login, PIM, sudo I/O, deploy, file-change and synchronisation evidence MUST be shipped to Sentinel in near-real time and retained per Section 10. Local deletion MUST NOT remove the shipped copy.
Detection: a host whose evidence streams are absent from Sentinel beyond the heartbeat interval. Why: root can erase local logs; it cannot erase what already left.
2.5 Success Criteria
| Criterion | Metric | Target |
|---|---|---|
| All human logins via Arc/Entra | sshd auth log: non-Arc human authentications | 0 |
| No shared or personal human SSH keys on hosts | authorized_keys files for human accounts | 0 |
| No standing Administrator Login for humans | Active (non-eligible) assignments | 0 |
No human in docker group | getent group docker across hosts | 0 humans |
| Deployer cannot write / read secrets / reach Docker | Acceptance test on uat (Section 11) | Pass |
| Decommission time to effect | Group removal → sessions killed + privilege removed | ≤ 5 min |
| Stale accounts | Accounts without live membership, per monthly review | 0 |
| Break-glass alerting | Deliberate drill raises alert | 100% |
| Routine work friction | Prompts per Operator sudo | 0 |
Document Navigation
| Previous | Index | Next |
|---|---|---|
| ← 1. Introduction | Table of Contents | 3. Architecture → |
End of Section 2