AWS Security Baseline for New Accounts

·


Before the first production workload

Most AWS security incidents trace back to a small set of missing basics, not to novel attacks. Exposed long-lived credentials, a public S3 bucket, a security group open to the world on port 22, a root account with no MFA. This is the baseline to close those off before anything production-facing goes live — not a complete security program, but the floor below which an account shouldn’t operate.

Root account hardening and MFA

The root user has unrestricted access to the account and cannot be fully restricted by IAM policy. It should not be used for day-to-day work, ever, after initial setup.

  • Enable MFA on the root account immediately — ideally hardware MFA (a FIDO security key) rather than a virtual MFA app, since a hardware key isn’t exposed if the phone it would otherwise live on is compromised.
  • Do not create access keys for the root user. If they exist, delete them.
  • Set a strong, unique password and store it in a password manager with restricted access — not in a shared document.
  • In a multi-account setup under AWS Organizations, apply the same hardening to the root user of every member account, not just the management account — each one is a separate root credential with the same unrestricted power.
  • Better still, stop having those credentials at all. Centralized root access for Organizations lets the management account (or a delegated administrator for IAM) delete member-account root credentials outright: “you can remove the root user password, access keys, signing certificates, and deactivate multi-factor authentication (MFA),” after which “member accounts can’t sign in to their root user or perform password recovery for their root user,” and newly created accounts have no root credentials by default (Centralize root access for member accounts, AWS docs). It has two separable capabilities — root credentials management (delete them) and privileged root actions in member accounts (perform the handful of tasks that genuinely need root from the centre). Enable the second if you enable the first, or you remove credentials with no sanctioned path to the tasks that still require them.
  • Note the residual: some tasks can still only be performed signed in as that account’s root user, recovered deliberately through the privileged-task flow using the account’s root email inbox — so that inbox remains a security-critical asset even after credentials are deleted. AWS’s advice is to delete the credentials again once the task is done.
  • Lock down root with a service control policy that denies root actions in member accounts where root has no legitimate purpose after setup — bearing in mind the SCP exemptions described below.
Where each security control actually belongs, from the organisation down to the workload PLACE A CONTROL AT THE LAYER THAT OWNS IT Organisation SCPs · centralised root access · delegated administrators Does not apply to the management account or service-linked roles Account Block Public Access · CloudTrail org trail · Config · Security Hub CSPM Security Hub depends on Config recording to evaluate most controls Network VPC boundaries · security groups · no route to the internet gateway A private subnet is defined by its route table, not its name Identity Identity Center organisation instance · roles, not long-lived keys Human access federated; workloads assume roles Data KMS CMK where the key-usage audit trail matters · Object Lock S3 encrypts new uploads by default (SSE-S3); the decision is which key A control placed one layer too high is unenforceable; one layer too low is unmaintainable. Where each security control actually belongs, from the organisation down to the workload PLACE A CONTROL AT THE LAYER THAT OWNS IT Organisation SCPs · centralised root access · delegated administrators Does not apply to the management account or service-linked roles Account Block Public Access · CloudTrail org trail · Config · Security Hub CSPM Security Hub depends on Config recording to evaluate most controls Network VPC boundaries · security groups · no route to the internet gateway A private subnet is defined by its route table, not its name Identity Identity Center organisation instance · roles, not long-lived keys Human access federated; workloads assume roles Data KMS CMK where the key-usage audit trail matters · Object Lock S3 encrypts new uploads by default (SSE-S3); the decision is which key A control placed one layer too high is unenforceable; one layer too low is unmaintainable.
Each control sits at the layer that can actually enforce it. Service control policies do not apply to the management account or to service-linked roles, and Security Hub cannot evaluate most controls without AWS Config recording.

IAM Identity Center over long-lived IAM users

Long-lived IAM user access keys are a standing liability: they don’t expire on their own, they get committed to repositories, they get embedded in CI configs, and the blast radius of a leaked key is however much access that user has, for however long it takes someone to notice.

IAM Identity Center (renamed from AWS Single Sign-On in July 2022; the sso API namespace is unchanged) replaces individual IAM users for human access with federated access from a central identity source — either users created directly in Identity Center or an existing identity provider synchronised in. AWS’s framing of the benefit is that you “only federate once” and have “only one certificate to manage” with a SAML 2.0 provider (What is IAM Identity Center, AWS docs). Use an organization instance, deployed in the Organizations management account — AWS calls it the best practice and the only instance type that can manage access to AWS accounts; account instances exist only for isolated application deployments. Users authenticate once, get temporary, auto-expiring credentials scoped by permission set, and administrators manage access centrally across every account in the organization rather than per-account IAM users that drift out of sync.

The practical rule: IAM users should be the exception, not the default, reserved for cases Identity Center genuinely can’t cover — some service accounts and break-glass access. Everyone and everything else gets federated access or, for workloads, IAM roles with temporary credentials via instance profiles, task roles, or OIDC federation (for CI/CD systems like GitHub Actions) — never a long-lived access key embedded in a pipeline.

Least privilege as an iterative practice

Least privilege is frequently treated as a one-time exercise: write a tight policy at launch, move on. In practice, the correct permission set for a role is rarely known on day one — teams either over-grant out of caution (* on a service, “just to get it working”) or under-grant and spend the first month fighting access-denied errors.

The practice that actually works is iterative:

  1. Start with a reasonably scoped policy, not *, informed by what the workload is known to need.
  2. Use IAM Access Analyzer’s policy generation, which examines CloudTrail activity for a role over an observation period and generates a policy matching what was actually used — a much better starting point than guessing.
  3. Review and tighten on a cadence, not just at creation. Unused permissions accumulate as workloads evolve; Access Analyzer’s unused-access findings surface permissions a role hasn’t exercised in a configurable window.
  4. Treat permission boundaries and SCPs as the backstop, not the primary control — they cap what even a misconfigured identity-based policy can grant, which matters when the iterative process above is, inevitably, imperfect somewhere.

This is organizationally harder than writing a policy once, which is exactly why it’s usually skipped. It needs to be someone’s recurring responsibility, not a launch checklist item.

SCPs as guardrails, not application logic

Service control policies, applied at the AWS Organizations level, set the outer boundary of what any identity in a member account can do — even an account administrator. AWS is unambiguous that they are not a grant mechanism: “SCPs do not grant permissions to the IAM users and IAM roles in your organization. No permissions are granted by an SCP” (Service control policies, AWS docs). Effective permissions are the intersection of what the SCP allows and what identity-based and resource-based policies allow.

Three exemptions matter more than the mechanics, because each is a place a guardrail silently does not apply:

  • SCPs have no effect on users or roles in the management account — including when the management account is acting on a member account’s resources. This is the single most common false sense of coverage in a landing zone. Keep workloads out of the management account entirely.
  • SCPs do not affect service-linked roles, which exist precisely so other AWS services can act and cannot be restricted this way.
  • A short list of tasks is not restrictable by SCP at all, including registering for the Enterprise support plan as the root user and providing CloudFront trusted-signer functionality.

SCPs do apply to the member account’s root user, which is what makes them a usable root guardrail. Use them for things that should never happen regardless of who is logged in: denying regions outside an approved list, denying the ability to disable CloudTrail or GuardDuty, preventing public S3 bucket policies account-wide, denying the ability to leave the organization. Don’t use SCPs as a substitute for application-level IAM policy — they operate at too coarse a level, and AWS itself “strongly recommends that you don’t attach SCPs to the root of your organization without thoroughly testing the impact.” Move accounts into a test OU one at a time. Also, don’t remove the default FullAWSAccess policy without replacing it: doing so causes all AWS actions from member accounts to fail.

Logging: CloudTrail, and where logs should live

CloudTrail records every API call made in an account — who, what, when, from where. Without it, a security incident is nearly impossible to reconstruct after the fact.

  • Enable an organization trail at the AWS Organizations management account level, applying to all member accounts, rather than relying on each account to configure its own trail correctly.
  • Send logs to S3 with Object Lock for immutability — note that Object Lock requires S3 Versioning on the bucket, and that only compliance mode resists deletion “by any user, including the root user in your AWS account”; governance mode can be bypassed by a principal holding s3:BypassGovernanceRetention (S3 Object Lock, AWS docs). For an evidence trail, that distinction is the control, not a detail. Send them to a dedicated logging account separate from the accounts generating the activity — this is the same principle as backup isolation: an attacker who compromises a workload account shouldn’t also be able to delete the evidence.
  • Enable log file integrity validation, which lets you cryptographically verify logs haven’t been tampered with after the fact — relevant evidentiary weight in an actual incident investigation.
  • CloudTrail answers “what happened and who did it.” It does not by itself answer “is this activity malicious” — that’s what the next layer is for.

GuardDuty, Security Hub, and Config: what each actually answers

These three get bundled together in marketing material but answer genuinely different questions:

ServiceQuestion it answersWhat it’s not
GuardDutyIs there malicious or anomalous activity happening right now? (compromised credentials, crypto-mining, unusual API calls, malware on EC2/EKS)Not a configuration checker — it detects behavior, not misconfiguration
Security Hub CSPMWhat’s my aggregate security posture across accounts, and how does it compare to a standard? It runs continuous control checks against the AWS Foundational Security Best Practices standard and external frameworks (CIS, PCI DSS, NIST), and receives findings from GuardDuty, Inspector, Macie and third-party products into one view (Introduction to Security Hub CSPM, AWS docs)Not purely an aggregator — it generates its own control findings too, which is why describing it as “just a dashboard” understates it. But it depends on AWS Config: Config must be enabled and recording resources for Security Hub to generate most control findings, and it only processes findings generated after you enable it, in the Region where you enabled it
ConfigIs this resource configured the way it’s supposed to be, and when did it change?Not real-time threat detection — it’s configuration history and compliance rules, useful for “when did this security group change” investigations and drift detection

Enable all three at the organization level if the account structure supports it. The combination — Config for drift, GuardDuty for active threats, Security Hub for standards checks and the rolled-up view — covers meaningfully different failure modes, and skipping one leaves a specific blind spot rather than a generic gap. Note the ordering dependency: enabling Security Hub without Config gets you an aggregator with most of its own controls unable to report. Also note that Security Hub is Regional in effect — for full CIS benchmark coverage AWS states you must enable it in all supported Regions, which is a real cost and operational consideration, not a checkbox.

S3 public access and encryption defaults

S3 Block Public Access should be enabled at the account level (and enforced via SCP at the organization level) by default, with exceptions granted deliberately per-bucket only when there’s a genuine reason — static website hosting behind CloudFront being the common legitimate case, and even then, routing through CloudFront with Origin Access Control rather than making the bucket itself public is usually the better pattern.

The old baseline item “enable S3 default encryption so a bucket isn’t silently storing unencrypted data” is no longer a task you need to do — and repeating it in a 2026 checklist is a sign the checklist hasn’t been reviewed. Since 5 January 2023, SSE-S3 using AES-256 “is automatically applied to all new buckets and to any existing S3 bucket that doesn’t already have default encryption configured,” all new object uploads are encrypted at no additional cost, and “you can no longer disable encryption for new object uploads” (Default encryption FAQ, AWS docs).

What remains a real decision is the key and the backfill:

  • SSE-KMS with a customer-managed key where the audit trail of key usage (who decrypted what, when) or key-policy-level access control matters for compliance. SSE-S3 gives you encryption at rest but not that audit trail. Setting this is still your job; the automatic baseline is SSE-S3, not KMS.
  • Objects that predate the change are not retroactively encrypted. AWS is explicit: “objects that are already in an existing unencrypted bucket won’t be automatically encrypted.” If you inherited an old estate and your control says “all objects at rest are encrypted,” you need an S3 Batch Operations pass to copy them, not an assumption.

VPC security group discipline

0.0.0.0/0 on port 22 (or 3389) keeps happening because it’s the fastest way to get unblocked during setup, and “fastest way to get unblocked” tends to survive into production because nobody circles back. The fix isn’t a reminder to engineers — it’s removing the reason they reach for it:

  • AWS Systems Manager Session Manager gives shell access to EC2 instances without any inbound port open at all, authenticated through IAM rather than SSH keys. This removes the reason to open port 22 in the first place for most operational access.
  • Where direct SSH/RDP is genuinely required, scope the source to a bastion host or VPN CIDR, never 0.0.0.0/0.
  • Use an SCP or Config rule to detect and alert on security groups with unrestricted ingress on sensitive ports — catching the ones that get added anyway.

Secrets management

Credentials, API keys, and database passwords belong in AWS Secrets Manager or Systems Manager Parameter Store (SecureString), not in environment variables baked into container images, not in source control, not in Lambda configuration as plaintext. Secrets Manager adds automatic rotation for supported database engines, which closes the gap where a credential, once issued, never changes for the life of the system.

A realistic order: week one vs. month three

Week one: root MFA and key removal, IAM Identity Center for human access, organization-wide CloudTrail to a dedicated logging account, S3 Block Public Access at the account level, GuardDuty enabled, security groups audited for 0.0.0.0/0 on admin ports.

Month three: SCP guardrails tuned per OU, Security Hub with a chosen standard baseline, Config rules for drift detection, IAM Access Analyzer integrated into the role-creation workflow, Secrets Manager rotation configured for production databases, and a first iteration of least-privilege tightening based on real Access Analyzer findings rather than guesses.

Trying to do all of this before week one’s deadline usually means none of it gets done well. The week-one list is the floor; everything else is iterative hardening that should keep happening for the life of the account, not a box to check once.

Related


More in this reference