47. AWS
This guide describes Lawliet 1.5.14.s (the current release). Screens, commands and procedures may change in later versions; the usage guide is updated with each release. Check the version your server runs under Settings > Platform or with ./lawliet version, and see the Releases page for what changed.
Lawliet reads an AWS estate - accounts, regions, networks, instances, storage, identity, logging - puts it on the network map and the asset list, judges it against 34 AWS controls, queues what is wrong, applies five safe fixes (with a second signature and one-click rollback), and installs the Lawliet agent on EC2 instances through Systems Manager.
Path: AWS (sidebar group Network & Data). Licensed with the compliance module. The Lawliet server must reach the AWS APIs over HTTPS (directly, through a proxy, or through VPC endpoints, 47.7). A fully disconnected site cannot use this integration; use agents and SSH/WinRM deployment instead.
Permissions:
| Task | Permission | Four-eyes |
|---|---|---|
| See connections, accounts, inventory, compliance, exposure, instances, the IAM policies | View cloud | - |
| Add, change or remove a connection | Manage cloud connections | yes - critical action "Change a cloud connection" |
| Test, sync now, show the external id | Manage cloud connections | no |
| Apply or roll back a fix | Change cloud resources | yes - "Change a cloud resource" |
| Install the agent through Systems Manager | Deploy agents remotely | yes - "Deploy agents remotely" |
47.1 How Lawliet signs in to AWS: two roles#
Each account gets:
- a read role (for example
LawlietReadOnly) with the shipped read policy. Every sync and test runs in it with the read policy also passed as a session policy, so a sync can never write - even if the role was given more; - optionally, a separate write role (for example
LawlietWrite) with the shipped write policy, used only for an approved fix or agent rollout, each time narrowed to that purpose. Without a write role the connection is read-only.
Lawliet reaches the roles in one of two ways:
| Sign-in | You give | When |
|---|---|---|
| Assume a role (recommended) (server identity) | The read role ARN (and the write role ARN) | The Lawliet server runs on EC2 with an instance profile, or has its own AWS identity. It is used only to assume the roles; no long-lived key is stored |
| Access key (optionally then a role) | An access key id and secret of an IAM user whose only right is to assume those roles, plus the role ARNs | Elsewhere |
External id. Lawliet generates one per connection when it is created - unique, never chosen by you, never changed. Put it in both roles' trust policies. It is shown to whoever creates the connection and afterwards with External id (audited); it is never part of an approval request.
IAM policies. Press Show IAM policies on the Connections tab: the Read role policy ("Everything a sync reads; nothing it writes."), the Write role policy (optional) ("The five four-eyes fixes and the SSM agent rollout (tagged instances only).") and the Trust policy (both roles) ("Lawliet's principal, only with the connection's external id."). Each has a copy button. These are exactly the calls Lawliet makes.
47.2 Procedure: connect an account#
Permission: Manage cloud connections. Four-eyes: yes.
Risk: none to AWS from the read role. Rollback: remove the connection (47.3).
Open AWS > Connections and press Show IAM policies. Create the read role (and, if you want fixes or the agent rollout, the write role) in each account with those policies. Leave the trust policy's external id for step 5.
Press Add connection and fill in:
Field What to enter Name For example productionSign-in Assume a role (recommended) or Access key (optionally then a role) Read role ARN arn:aws:iam::<account>:role/LawlietReadOnly- "Every sync runs in this role, under the read policy."Write role ARN (optional) "Only for approved fixes and the agent rollout. Empty = read-only." Access key id, Secret access key Access key sign-in only. "Stored encrypted; never shown again." Regions all(every region enabled in the account) or a list:eu-west-1, eu-central-1Home region For global calls (default us-east-1;us-gov-west-1orcn-north-1in those partitions)HTTPS proxy (optional) http(s)://host:port, no credentials in the URL (47.7)Organization Tick Read every account of the organisation (management account) for a management (or delegated administrator) account, and give the member read role name (default LawlietReadOnly) and member write role name (defaultLawlietWrite)Press Save (needs a second signature). "Sent for approval: a second administrator signs it in Approvals before it is stored." The approver sees the roles, the last characters of the key, the regions and any proxy - never the secret, the key id or the external id. Execute it from Approvals > My requests.
The console shows "External id for connection #N (put it in both roles' trust policy): <value>" with a copy button. (Later: External id on the connection's card.)
Put the external id in both roles' trust policies. For an organisation, deploy the member roles with a CloudFormation StackSet using the same external id.
Press Test: "<name>: reached account <id> as <caller ARN> (N regions enabled)."
Press Sync now. The run shows its status and, when done, "N resources, M failing, K passing, J review item(s)", with any per-service errors.
If it fails:
| What you see | Cause | Fix |
|---|---|---|
| Test: AccessDenied on assuming the role | Trust policy missing the external id or Lawliet's principal | Fix the trust policy |
| Sync partial, "<account> <region> <service>: <error>" | The role cannot read a service, or a region is not enabled | Add the missing permission from the read policy; that service's controls show error, never pass |
| An account shows no access under Accounts | The member role is missing in that account | Deploy it; the account is never silently skipped |
47.3 Change or remove a connection#
Remove: Remove on the card. "Remove the connection <name>? Its inventory, results and map entries go with it." Four-eyes: yes ("Removal sent for approval.").
Change (keys, roles, regions, proxy): there is no edit form in this release. Use PUT /api/v1/cloud/aws/connections/{connection_id}; four-eyes yes. The external id never changes.
47.4 What is read, and the other tabs#
A sync reads, read-only: VPCs and flow logs, subnets, route tables, Internet and NAT gateways, security groups, network ACLs, customer prefix lists; EC2 instances (AMI, addresses, IMDS setting, instance profile, volumes, SSM status); EBS encryption, default encryption, public snapshots; S3 Block Public Access, encryption, public policy, ACL grants, HTTPS-only; the IAM credential report and password policy; RDS, load balancers, Lambda; CloudTrail, AWS Config, GuardDuty; KMS key rotation. Global services are read once per account.
| Tab | Shows |
|---|---|
| Accounts | Per connection, its accounts (management marked; access read or why not) and per region its resource count and failing controls |
| Inventory | Type and Search (id, name or ARN), Find; Type, Id / name, Account / region, Details, Agent (enrolled or none for instances). Click a row for its controls and what was read |
| Compliance | 47.5 |
| Network | Reachable from the Internet (Instance, Account / region, Port, How), Unknown: behind an inspection endpoint, and regions whose network could not be read (not assessed) |
| Agents | 47.6 |
With several connections, a Connection list on each tab narrows it (All by default).
Exposure. An instance is reachable from the Internet when the Internet reaches it on a port through its public or Elastic address (its own security groups, the subnet's network ACL in rule order, a route to an Internet gateway), or through an internet-facing load balancer to its targets. Address sets count as "the Internet" when large enough (for example 0.0.0.0/1 + 128.0.0.0/1, or a customer prefix list holding 0.0.0.0/0). A route through a Gateway Load Balancer or Network Firewall endpoint is reported unknown, never "not exposed".
Map and assets. Every instance becomes a node on Network (source Cloud), every subnet a zone, with one Internet node per connection and edges for reachable ports. Each instance gets an asset profile tagged aws, aws:account:<id>, aws:region:<name>. An instance is linked to an enrolled agent by instance id only when the agent proved it with the AWS-signed instance identity document (agent 2.1.10.s), else by an address only one instance has.
47.5 Compliance and the five fixes#
Compliance tab: Score, Controls passing (passing / judged), Failing, Not readable; Only failing or unreadable controls; then each control (fail count, fixable when Lawliet can fix it). Open a control for If enforced: (the impact), Fix it yourself (the exact AWS CLI command, with a copy button), and its failing resources with Fix.
The 34 controls cite CIS AWS Foundations v3.0.0 and AWS Foundational Security Best Practices. Critical and high failures go to the review queue (module AWS) with the exact fix, and close themselves when a later sync no longer finds them.
Lawliet fixes only these, where the change is safe and exactly reversible:
| Control | Fix | Refused while |
|---|---|---|
| AWS-S3-ACCOUNT-PUBLIC-ACCESS-BLOCK | All four account-level Block Public Access settings on | Any bucket serves the public by policy or ACL |
| AWS-S3-BUCKET-PUBLIC-ACCESS-BLOCK | All four bucket-level settings on | The bucket serves the public by policy or ACL grants |
| AWS-EC2-EBS-DEFAULT-ENCRYPTION | EBS encryption by default (new volumes only) | - |
| AWS-KMS-ROTATION-OFF | Automatic key rotation on | - |
| AWS-LOGGING-CLOUDTRAIL-VALIDATION | Log file validation on | - |
Everything else is report-only: closing SSH to the world, enforcing IMDSv2 or removing a public grant can break things only the owner can judge.
Procedure: apply a fix#
Permission: Change cloud resources; the connection needs a write role. Four-eyes: yes.
Risk: the setting changes in the live account. Rollback: Roll back (below).
- Open the control, press Fix on the resource ("Fixing...").
- "Sent for approval. After a second administrator signs it, run it from Approvals." Execute it from Approvals > My requests.
- The guards run against the live account (not the last sync), the prior value is recorded first, the change is made and read back.
What you see: "Fixed and validated: <control> on <resource>." It is listed under Fixes applied by Lawliet (When, Control, Resource, Status, Before).
Procedure: roll back a fix#
Permission: Change cloud resources. Four-eyes: yes (the approver reads which fix is undone). Press Roll back on the fix ("Rollback sent for approval."), then execute it.
What you see: "Rolled back <control> on <resource> to its recorded value." Rollback refuses if the setting changed since the fix - someone may have set it on purpose.
47.6 Procedure: install the agent through Systems Manager#
Agents tab: every EC2 instance with its Systems Manager state.
Permission: Deploy agents remotely; the connection needs a write role (the write policy allows the rollout only on tagged instances). Four-eyes: yes.
Risk: the agent is installed as root or Administrator on each instance. Rollback: uninstall the agent (11.6, 12.9).
- Under Install through Systems Manager, tick the online instances (one connection at a time: "Pick instances of one connection at a time.").
- Check Server address the instances reach.
- Press Install agent (N). "Sent for approval (deploy agents). Run it from Approvals once a second administrator signs it." The request names each instance by account, region and instance id - that is what the approver signs.
- Execute it. "Install sent to N instance(s) through SSM."
- Under Rollouts, press Refresh for each instance's status (Pending, InProgress, Success, Failed).
How the enrolment is protected: one enrolment code per account, region and platform, usable by exactly the number of instances selected, valid 2 hours, bound to those instance ids (the agent must present the instance's AWS-signed identity document), and revoked by a background watcher when every instance has finished. The code is visible in the account's SSM command history to whoever may read it; the binding, the cap, the 2-hour life and the revocation bound that. Command output is stored with enrolment codes removed.
Instances Not managed by Systems Manager are listed with their state; Copy addresses and deploy them with Remote deployment over SSH or WinRM (chapter 13).
47.7 Restricted networks#
- Proxy: set HTTPS proxy on the connection. All AWS calls of that connection go through it; its approver sees it.
- VPC endpoints (server inside AWS): interface endpoints with private DNS for
sts,ec2,ssm,rds,elasticloadbalancing,lambda,cloudtrail,config,guardduty,kms, and the S3 gateway endpoint. IAM and Organizations have no interface endpoints in most regions: they need the proxy, or egress toiam.amazonaws.comandorganizations.us-east-1.amazonaws.com.

