Least Privilege Access Design
by @quochungto
Analyze a system's access patterns and design least-privilege controls: classify data and APIs by risk, select the narrowest API surface for each operation,...
clawhub install bookforge-least-privilege-access-designπ About This Skill
name: least-privilege-access-design description: | Analyze a system's access patterns and design least-privilege controls: classify data and APIs by risk, select the narrowest API surface for each operation, define authorization policies with multi-party approval for sensitive actions, establish emergency access override procedures, and optionally introduce a controlled-access production proxy. Use when reviewing access controls for an existing system, designing authorization for a new service, auditing whether engineers have more permissions than their roles require, deciding whether to use a bastion or proxy for privileged operations, or hardening administrative API surfaces against insider mistakes and external compromise. Produces an access classification report, API surface recommendations, authorization policy decisions, and emergency override guidelines. version: 1.0.0 homepage: https://github.com/bookforge-ai/bookforge-skills/tree/main/books/building-secure-and-reliable-systems/skills/least-privilege-access-design metadata: {"openclaw":{"emoji":"π","homepage":"https://github.com/bookforge-ai/bookforge-skills"}} status: draft depends-on: [] source-books: - id: building-secure-and-reliable-systems title: "Building Secure and Reliable Systems" authors: ["Heather Adkins", "Betsy Beyer", "Paul Blankinship", "Piotr Lewandowski", "Ana Oprea", "Adam Stubblefield"] chapters: [3, 5] tags: - security - access-control - least-privilege - authorization - zero-trust - multi-party-authorization - audit-logging - api-design - administrative-api - breakglass - proxies - sre - reliability execution: tier: 2 mode: full inputs: - type: codebase description: "Service codebase, infrastructure config, IAM policy files, or API definitions revealing current access patterns and permission grants" - type: document description: "Architecture diagram, role/permission inventory, runbook, or written system description if no codebase is directly accessible" tools-required: [Read, Write] tools-optional: [Grep, Bash] mcps-required: [] environment: "Run inside a project directory with codebase, config, or architecture artifacts. Falls back to structured interview with the engineer." discovery: goal: "Produce a written access classification report: data/API risk ratings, API surface recommendations, authorization policy decisions, emergency override guidelines, and a controlled-access proxy recommendation if applicable" tasks: - "Inventory all data stores and APIs; classify each by Public / Sensitive / Highly Sensitive" - "Classify each access type (read / write / infrastructure) and assign a risk level per cell" - "Evaluate current API surface against least-privilege: identify oversized APIs and recommend narrow functional replacements" - "Select authorization controls for each risk level: ACL, multi-party authorization, temporary access, structured business justification" - "Define emergency access override policy: who can invoke it, under what conditions, and how it is audited" - "Recommend a controlled-access production proxy if fine-grained controls are unavailable or insufficient" - "Design audit log strategy: granularity, structured justification, auditor selection" audience: roles: ["security-engineer", "software-engineer", "site-reliability-engineer", "platform-engineer", "tech-lead", "software-architect"] experience: "intermediate-to-advanced β assumes familiarity with IAM concepts, API design, and distributed systems" triggers: - "Reviewing or auditing access controls for an existing system" - "Designing authorization for a new service or administrative API" - "Deciding whether a bastion host or production proxy is needed for privileged operations" - "Hardening a system where engineers have more permissions than their roles require" - "Post-incident review reveals an outage caused by an overly permissive admin operation" - "Preparing for a security review or compliance audit" - "Reducing the blast radius of a potential account compromise" not_for: - "Authentication mechanism selection (e.g., OAuth vs. mTLS) β covered separately" - "Network topology and firewall rule design" - "Application-layer threat modeling β use adversary-profiling-and-threat-modeling"
When to Use
Use this skill when you need to systematically reduce the damage any one user, automation, or compromised credential can cause β by granting only the access needed and no more.
Invoke it for:
Do not invoke it for selecting the cryptographic authentication mechanism, designing network segmentation, or full threat modeling β those are separate concerns.
Context and Input Gathering
Before designing least-privilege controls, gather the following:
1. Data inventory: What data stores does the system hold or access? What is in each? Who currently has access? 2. API inventory: What interfaces does the system expose β user-facing, administrative, setup/teardown, maintenance/emergency? For each: what can a caller read, write, or modify? 3. Role inventory: What human roles (engineers, SREs, support staff, on-call) and automated roles (CI/CD, batch jobs, monitoring agents) access the system? What do they actually need? 4. Current access breadth: Are any roles granted interactive shell access, broad IAM policies, or "owner"-level credentials? Does any automation run as a privileged user beyond what its task requires? 5. Authorization mechanism in place: ACL? IAM policy? Role-based groups? Is there a shared authorization library or each service rolls its own? 6. Audit coverage: Are administrative actions logged? Is each log entry attributable to a specific person and action? Is there a review process? 7. Emergency access story: How do on-call engineers recover from a bad policy update or auth system failure? Is there a procedure, and is it tested?
If a codebase is available, search for:
.authorized_keys filesProcess
Step 1 β Classify Data and APIs by Risk
WHY: Not all data and actions carry the same blast radius. Treating everything uniformly either over-controls low-risk operations (hurting productivity) or under-controls high-risk ones (accepting unnecessary exposure). A classification framework makes the trade-off explicit and consistently applied.
Classify each data store and API using the access classification matrix. For each resource, determine its sensitivity category and then assess risk by access type:
Sensitivity categories:
| Category | Definition | |---|---| | Public | Open to anyone in the organization; limited business impact if exposed | | Sensitive | Limited to groups with a documented business purpose; medium impact if exposed or corrupted | | Highly Sensitive | No permanent access; high impact if exposed, corrupted, or deleted (PII, cryptographic secrets, billing data, user credentials) |
Risk by access type (per Table 5-1, Chapter 5):
| | Read access | Write access | Infrastructure access | |---|---|---|---| | Public | Low risk | Low risk | High risk | | Sensitive | Medium/high risk | Medium risk | High risk | | Highly Sensitive | High risk | High risk | High risk |
Infrastructure access β the ability to change ACLs, reduce logging levels, gain direct shell access, restart services, or otherwise affect service availability β is high risk for all sensitivity levels. A read of publicly available data can still enable catastrophic abuse if it bypasses normal access controls.
Output of this step: a classification table listing each data store, API group, and role, with its assigned sensitivity category and the risk level per access type.
Step 2 β Evaluate and Narrow the API Surface
WHY: A large API surface is the root cause of most over-privilege. When users or automation connect via a broad interface (an interactive shell, a general-purpose admin API, a root-level process), the system can't distinguish what they actually need from what they could do. Narrowing the API to the minimum set of operations required makes it possible to grant the minimum permission and to audit actions precisely.
For each administrative API or access pathway, assess:
abc123" is.Use the API selection tradeoff matrix (per Table 5-2, Chapter 5 β configuration distribution example):
| API approach | API surface | Auditability | Can express least privilege | Complexity | |---|---|---|---|---| | POSIX API via SSH | Large | Poor | Poor | High | | Software update / package manager API | Varies | Good | Varies | High, but reusable | | Custom scoped command (e.g., SSH ForceCommand) | Small | Good | Good | Low | | Custom HTTP/RPC sidecar | Small | Good | Good | Medium |
Design rule: Make each API endpoint do one thing well. When you need a new operation, build a new narrow endpoint rather than extending an existing broad one. This applies equally to user-facing APIs and administrative APIs.
For existing systems with broad APIs (e.g., SSH access to all hosts): 1. Identify the specific operations that are actually performed through the broad interface 2. Build a narrow API for each operation category, with input validation and structured logging 3. Restrict the broad interface to a controlled emergency override path (see Step 5) 4. Progressively migrate callers to the narrow API
Step 3 β Select Authorization Controls Per Risk Level
WHY: The appropriate authorization control depends on the risk of the action. Binary yes/no ACLs are sufficient for low-risk reads; high-risk writes on sensitive data require additional controls that distribute trust across multiple parties and create an auditable record.
Match each classified operation to one or more of the following controls:
Access control list (ACL) / group membership β appropriate for:
Multi-party authorization (multi-person approval) β appropriate for:
Business justification (structured) β appropriate for:
Temporary access β appropriate for:
Three-factor authorization β appropriate for:
For highly sensitive infrastructure operations, combine controls: multi-party authorization + temporary access + structured business justification.
Step 4 β Design the Audit Strategy
WHY: Authorization controls are only as effective as the audit mechanism that detects when they are circumvented or abused. The value of a narrow API comes not just from preventing misuse, but from making every action attributable and reviewable. Without deliberate audit design, audit logs become noise that nobody reviews.
Audit log requirements:
Granularity: Small functional APIs provide the largest audit advantage. "User pushed config with hash abc123 to host group web-frontend" enables strong assertions. "User opened SSH session" does not. Interactive session transcripts (bash history, script(1)) appear comprehensive but can be bypassed by any user who is aware of their existence.
Auditor selection:
Emergency override audit: Emergency override (breakglass) events must always be reviewed. Weekly team review of all emergency override usage from the previous shift is a practical pattern β it creates cultural accountability and signals when the narrow API is insufficient for real operational needs (which should trigger a fix to the normal API, not normalization of emergency override use).
Step 5 β Define the Emergency Access Override Policy
WHY: Any authorization system can fail. A bad policy update, a misconfigured ACL, or an urgent production incident may require access that the normal authorization path cannot provide in time. Without a pre-defined, tested emergency access mechanism, engineers will improvise β which introduces uncontrolled risk. With a well-designed one, you get a controlled escape valve that is tightly audited.
Define the emergency access override policy with the following properties:
Access restriction: Emergency override access should be available only to the team directly responsible for the service's operational SLA (typically the SRE team). It should not be broadly available to all engineers.
Location restriction (for zero trust network access): If the service uses zero trust network access (access based on user and device credentials, not network location), the emergency override for bypassing the zero trust control should be available only from specific, physically secured locations with additional physical access controls β sometimes called "panic rooms." This is an intentional exception to the "network location doesn't grant trust" principle, offset by physical controls.
Monitoring: All uses of emergency override must be logged and reviewed. Emergency override use should be rare and surprising. Routine use signals that the normal API is inadequate and must be fixed.
Testing: The emergency override mechanism must be tested regularly by the team responsible for the service. A mechanism that has never been tested may not work when it is needed.
Graceful failure: Design the authorization system to fail in a known, diagnosable way. When a caller is denied access, the denial message should include information proportional to the caller's privilege level β nothing for unprivileged callers (no information disclosure), remediation steps for authorized callers who are incorrectly denied. Provide a denial token that can be used to open a support ticket rather than requiring the caller to describe the failure from memory.
Step 6 β Evaluate Whether a Controlled-Access Production Proxy Is Needed
WHY: When fine-grained controls for backend services are not available β because the service is third-party, legacy, or too costly to modify β a controlled-access production proxy can layer authorization, auditing, rate limiting, and multi-party approval on top of the existing interface without requiring changes to the underlying system.
A controlled-access production proxy is appropriate when:
A controlled-access production proxy provides:
Proxy risks and mitigations:
Key Principles
Least privilege applies to humans, automation, and machines equally. The objective extends through all authentication and authorization layers. Automation credentials often accumulate permissions over time β review them with the same rigor as human roles.
Avoid ambient authority. Users and automation should not hold standing access to sensitive resources they do not currently need. Temporary access that expires is always preferable to permanent standing access.
Design for the realistic threat model, not the idealized one. Engineers make typos. Accounts get compromised. Credentials are phished. A system that requires perfect human execution to remain secure is not secure. Design to limit the damage of realistic failure modes.
Small APIs make everything else possible. Narrow, functional APIs are the prerequisite for meaningful audit logs, meaningful least privilege, and meaningful multi-party authorization. A system built on broad interactive APIs cannot be audited or constrained effectively regardless of other controls.
Authorization infrastructure should be shared, not per-service. Separate authorization logic into a shared library or service. This enables org-wide controls (multi-party authorization, multi-factor authorization) to be added at a single layer rather than requiring changes to every service. Standardization also enables team mobility and consistent policy reasoning.
Culture enforces what technology cannot. Multi-party authorization only works if approvers feel genuinely empowered to reject suspicious requests. Emergency override use only remains rare if teams review it regularly and treat frequent use as a signal that the normal API needs improvement. Controls without cultural reinforcement become rubber stamps.
Examples
Example 1 β Controlled-Access Production Proxy (Safe Proxy Pattern)
Scenario: An infrastructure team runs a fleet of production servers. Engineers use command-line tools directly against the fleet for administrative tasks. These tools are potentially dangerous β an incorrect scope selector could stop multiple service frontends simultaneously. Centralized logging and authorization are not enforced.
Problem: No audit trail. Engineers can issue arbitrary commands to production. A single engineer account compromise or fat-finger mistake could take down significant fleet capacity.
Least-privilege design:
1. Classify: The fleet's command-line interface is an infrastructure-level API. By the classification matrix: high risk for all sensitivity levels.
2. Narrow the API: Introduce a controlled-access production proxy that exposes a defined set of RPCs. Each RPC corresponds to a specific administrative action (restart a job, push a config, check status). The underlying servers are reconfigured to accept connections only from the proxy β not directly from engineer workstations.
3. Authorization policy: The proxy enforces an ACL per RPC. For sensitive operations (e.g., stopping a job in production), the proxy triggers multi-party authorization β an engineer in the admin group must have a peer in admin-leads approve before the command executes.
4. Audit: The proxy logs every RPC, the identity of the caller, the parameters, and whether it was approved. Log entries are structured and associated with the requester's ticket or incident number.
5. Emergency override: Engineers who genuinely need direct access during an incident can invoke an emergency override mechanism. All emergency override uses are reviewed weekly by the team.
Result: ~13% of production outages that would have been caused by direct human access to production become preventable. The blast radius of any single mistake or compromise is bounded by the rate limiter and multi-party approval requirements.
Proxy policy structure (conceptual):
config {
proxy_role = 'admin-proxy'
tools {
restart_job {
allow = ['group:admin']
require_approval_from = ['group:admin-leads']
rate_limit = { max_per_minute = 5 }
}
status_check {
allow = ['group:admin', 'group:sre']
# No approval required β read-only, low risk
}
}
}
Example 2 β Configuration Distribution API Design
Scenario: An automation system needs to push a validated configuration file to all web servers in a fleet. The naive approach: SSH to each host as the user the web server runs as, write the file, restart the process.
Problem: The SSH approach exposes the entire POSIX API. The automation role can read any data on the host, stop the web server permanently, start arbitrary binaries, or cause a coordinated outage of the entire fleet. A compromise of the automation credential is equivalent to a compromise of every web server.
Least-privilege design using Table 5-2 logic:
1. Classify: Web server configuration write is a write operation on a public service β medium risk. Infrastructure access (ability to restart the service) is high risk. 2. Evaluate API options: - POSIX API via SSH: large surface, poor auditability, poor least-privilege expression β reject - Software update API (e.g., package manager): good auditability, reusable infrastructure, but complexity is high and convergence timing may not meet requirements - Custom SSH ForceCommand: small surface, good auditability, low complexity β viable - Custom HTTP receiver (sidecar): small surface, good auditability, medium complexity β preferred for scale 3. Design the narrow API: A small sidecar process accepts a configuration payload via an authenticated RPC, validates its structure and signature, writes the file to the correct path, and restarts the web server. The automation role is authorized only to call this single RPC β it cannot read other files or run other processes. 4. Segment trust further: The signing of the configuration is performed by a separate role (the code review / release system), independent from the automation role that pushes it. Even if the push automation is compromised, it cannot push an arbitrary config β only content that has been signed by the release system. 5. Audit: Each push logs the config hash, the target host group, and the result. Rejected configs (invalid signature, schema validation failure) are logged for investigation.
Result: A compromise of the push automation credential cannot write arbitrary content to hosts or run arbitrary processes. The blast radius is limited to pushing a valid (signed) config β which itself requires compromise of the signing system.
Example 3 β Support Staff Access to Customer Data
Scenario: Customer support representatives need to access customer account records to resolve tickets. Currently, all support staff have read access to all customer records for all customers at all times.
Problem: Overly broad read access to highly sensitive data. A support staff compromise, or a malicious insider, can exfiltrate all customer data without any specific trigger.
Least-privilege design:
1. Classify: Customer records are highly sensitive. Read access is high risk. 2. Authorization control: Replace standing read access with structured business justification β access to a customer's record is only permitted when a support case for that customer is open and assigned to this representative. 3. Implementation path (incremental): - Phase 1: Require a support ticket ID for any customer data access. Log the association between the ticket and the access event. - Phase 2: Validate that the ticket exists, is open, and is assigned to the requesting representative before granting access. - Phase 3: Restrict access to only the specific customer's data associated with the open ticket, rather than all customers. - Phase 4: Add time bounds β access expires when the ticket is closed. 4. Audit: Every customer data access is logged with the associated ticket ID. A programmatic check verifies that access events correspond to open tickets. Anomalies (access with no ticket, access after ticket closure, bulk reads) trigger alerts.
Result: The data surface exposed to any single support interaction is the minimum needed to resolve that case. A compromised support account can only access data for currently open tickets assigned to it β not the entire customer database.
References
Cross-references:
adversary-profiling-and-threat-modeling β identify which adversaries and attack paths make least-privilege controls most valuableLicense
This skill is licensed under CC-BY-SA-4.0. Source: BookForge β Building Secure and Reliable Systems by Heather Adkins, Betsy Beyer, Paul Blankinship, Piotr Lewandowski, Ana Oprea, Adam Stubblefield.
Related BookForge Skills
This skill is standalone. Browse more BookForge skills: bookforge-skills
β‘ When to Use
π‘ Examples
Example 1 β Controlled-Access Production Proxy (Safe Proxy Pattern)
Scenario: An infrastructure team runs a fleet of production servers. Engineers use command-line tools directly against the fleet for administrative tasks. These tools are potentially dangerous β an incorrect scope selector could stop multiple service frontends simultaneously. Centralized logging and authorization are not enforced.
Problem: No audit trail. Engineers can issue arbitrary commands to production. A single engineer account compromise or fat-finger mistake could take down significant fleet capacity.
Least-privilege design:
1. Classify: The fleet's command-line interface is an infrastructure-level API. By the classification matrix: high risk for all sensitivity levels.
2. Narrow the API: Introduce a controlled-access production proxy that exposes a defined set of RPCs. Each RPC corresponds to a specific administrative action (restart a job, push a config, check status). The underlying servers are reconfigured to accept connections only from the proxy β not directly from engineer workstations.
3. Authorization policy: The proxy enforces an ACL per RPC. For sensitive operations (e.g., stopping a job in production), the proxy triggers multi-party authorization β an engineer in the admin group must have a peer in admin-leads approve before the command executes.
4. Audit: The proxy logs every RPC, the identity of the caller, the parameters, and whether it was approved. Log entries are structured and associated with the requester's ticket or incident number.
5. Emergency override: Engineers who genuinely need direct access during an incident can invoke an emergency override mechanism. All emergency override uses are reviewed weekly by the team.
Result: ~13% of production outages that would have been caused by direct human access to production become preventable. The blast radius of any single mistake or compromise is bounded by the rate limiter and multi-party approval requirements.
Proxy policy structure (conceptual):
config {
proxy_role = 'admin-proxy'
tools {
restart_job {
allow = ['group:admin']
require_approval_from = ['group:admin-leads']
rate_limit = { max_per_minute = 5 }
}
status_check {
allow = ['group:admin', 'group:sre']
# No approval required β read-only, low risk
}
}
}
Example 2 β Configuration Distribution API Design
Scenario: An automation system needs to push a validated configuration file to all web servers in a fleet. The naive approach: SSH to each host as the user the web server runs as, write the file, restart the process.
Problem: The SSH approach exposes the entire POSIX API. The automation role can read any data on the host, stop the web server permanently, start arbitrary binaries, or cause a coordinated outage of the entire fleet. A compromise of the automation credential is equivalent to a compromise of every web server.
Least-privilege design using Table 5-2 logic:
1. Classify: Web server configuration write is a write operation on a public service β medium risk. Infrastructure access (ability to restart the service) is high risk. 2. Evaluate API options: - POSIX API via SSH: large surface, poor auditability, poor least-privilege expression β reject - Software update API (e.g., package manager): good auditability, reusable infrastructure, but complexity is high and convergence timing may not meet requirements - Custom SSH ForceCommand: small surface, good auditability, low complexity β viable - Custom HTTP receiver (sidecar): small surface, good auditability, medium complexity β preferred for scale 3. Design the narrow API: A small sidecar process accepts a configuration payload via an authenticated RPC, validates its structure and signature, writes the file to the correct path, and restarts the web server. The automation role is authorized only to call this single RPC β it cannot read other files or run other processes. 4. Segment trust further: The signing of the configuration is performed by a separate role (the code review / release system), independent from the automation role that pushes it. Even if the push automation is compromised, it cannot push an arbitrary config β only content that has been signed by the release system. 5. Audit: Each push logs the config hash, the target host group, and the result. Rejected configs (invalid signature, schema validation failure) are logged for investigation.
Result: A compromise of the push automation credential cannot write arbitrary content to hosts or run arbitrary processes. The blast radius is limited to pushing a valid (signed) config β which itself requires compromise of the signing system.
Example 3 β Support Staff Access to Customer Data
Scenario: Customer support representatives need to access customer account records to resolve tickets. Currently, all support staff have read access to all customer records for all customers at all times.
Problem: Overly broad read access to highly sensitive data. A support staff compromise, or a malicious insider, can exfiltrate all customer data without any specific trigger.
Least-privilege design:
1. Classify: Customer records are highly sensitive. Read access is high risk. 2. Authorization control: Replace standing read access with structured business justification β access to a customer's record is only permitted when a support case for that customer is open and assigned to this representative. 3. Implementation path (incremental): - Phase 1: Require a support ticket ID for any customer data access. Log the association between the ticket and the access event. - Phase 2: Validate that the ticket exists, is open, and is assigned to the requesting representative before granting access. - Phase 3: Restrict access to only the specific customer's data associated with the open ticket, rather than all customers. - Phase 4: Add time bounds β access expires when the ticket is closed. 4. Audit: Every customer data access is logged with the associated ticket ID. A programmatic check verifies that access events correspond to open tickets. Anomalies (access with no ticket, access after ticket closure, bulk reads) trigger alerts.
Result: The data surface exposed to any single support interaction is the minimum needed to resolve that case. A compromised support account can only access data for currently open tickets assigned to it β not the entire customer database.