What is the operational difference between an AWS IAM Role and an IAM User, and when exactly would a system require a Service-Linked Role?
Quick Answer
An IAM User represents a persistent identity with long-lived credentials (a password and/or access keys) meant for a human or a single fixed application, while an IAM Role has no credentials of its own and is instead assumed temporarily by a trusted identity, issuing short-lived STS tokens that automatically expire — making roles the correct choice for anything that shouldn't hold a permanent secret, including AWS services themselves. A Service-Linked Role is specifically required when an AWS service needs to make API calls into other AWS services on your behalf with a permission set that AWS itself predefines and locks down (you can't broaden it), commonly seen with services like Auto Scaling, Elastic Load Balancing, or AWS Organizations that must reach into EC2 or other services to do their job automatically without you manually wiring up a custom role.
Detailed Answer
Think of an IAM User like an employee badge with a photo and a permanent PIN code, valid indefinitely until someone in security manually deactivates it — if that badge is lost or copied, whoever has it can walk in whenever they want until someone notices and revokes it. An IAM Role is more like a visitor badge that a receptionist hands out after checking ID at the front desk: it works for a few hours, expires automatically, and the visitor never actually possesses a permanent credential — even if someone photographs the visitor badge, it's useless the next day.
AWS designed this distinction specifically around credential lifecycle risk: IAM Users hold durable secrets (access keys that don't expire on their own, passwords protected only by rotation policy), which is exactly the shape of credential that ends up leaked in GitHub repos, laptop backups, or CI logs, because it's meant to be reused indefinitely. IAM Roles solve this by never handing out a durable secret at all — instead, a trusted principal (a user, an EC2 instance, a Lambda function, another AWS account, or an AWS service itself) calls sts:AssumeRole, and STS issues a temporary credential set (access key, secret key, and session token) that's valid for a bounded window, typically 15 minutes to 12 hours, after which it's cryptographically useless even if somehow exposed.
Internally, this is why EC2 instance profiles, ECS task roles, and Lambda execution roles are all IAM Roles rather than Users with embedded keys — an application running on an EC2 instance queries the instance metadata service, which itself talks to STS to fetch fresh temporary credentials automatically, rotating them behind the scenes without the application ever needing to store or manage a secret. This is a foundational shift in the security model: the credential simply cannot be exfiltrated in a way that remains useful for long, which is precisely why 'never use long-lived access keys for applications, only roles' is close to a universal best practice at any AWS shop with a real security program.
A Service-Linked Role exists for a narrower, more specific reason: some AWS services need to reach into other AWS services on your behalf to perform automated background actions — Auto Scaling launching and terminating EC2 instances, Elastic Load Balancing registering targets, RDS creating ENIs for Multi-AZ — and AWS predefines exactly what permissions that service needs, locks the role's trust policy and (often) its permissions policy so you cannot accidentally over-scope or under-scope it, and links the role's lifecycle to the resource using it (deleting the last Auto Scaling group referencing the role allows the role itself to be deleted, whereas a normal role could be deleted while still in active use, breaking things silently). This matters operationally because a hand-rolled custom role for the same purpose risks either being too permissive (a security finding) or missing a permission AWS added in a later API version update, which is exactly the class of bug Service-Linked Roles are designed to eliminate by having AWS itself own and maintain the permission set.
The non-obvious gotcha: you cannot always predict when a service silently requires a Service-Linked Role until you hit a permission error creating a specific resource — for example, enabling AWS Organizations' consolidated billing or certain ELB features auto-creates a service-linked role behind the scenes on first use, and in tightly locked-down accounts where IAM role creation itself is restricted via an SCP, this first-use auto-creation can fail with a cryptic access-denied error that has nothing to do with the actual resource you're trying to create, since the real blocker is the account's inability to create the prerequisite service-linked role at all.