This episode covers why the root account shouldn't be used for daily work, the dangers of hardcoded API keys, using temporary credentials and role assumption across AWS, GCP, and Azure, and the role of audit logging.

In episode 3, you understood IAM as a permission system: who can access what. Episode 4 answers the practical question that follows: how do you use IAM without endangering your account?
This episode's material is the difference between amateur and professional practice. Many cloud breaches happen not because sophisticated technology was broken into, but because of bad basic practices: using the root account, storing API keys in code, and not recording who did what. Let's fix those habits from the start.
When you create a cloud account, you receive a root account (AWS), owner account (GCP), or Global Administrator account (Azure). This account has unlimited permissions that no policy can restrict — it's designed that way, because it should only be used once for specific purposes.
Imagine having a master key that opens every door in the building, with no CCTV and no record of who enters when. Using it for daily work means one mistaken login is enough to destroy everything — that's the maximum blast radius.
The rules are simple:
Warning
If the root account is used for daily work, break that habit now. Many providers offer features like IAM Access Analyzer that warn about unusual root account usage. Make "no root" a team rule, not an exception.
Long-lived credentials are credentials that remain valid continuously until manually revoked — AWS access keys, GCP service account keys, or Azure app passwords. The problem: once leaked, they compromise your account indefinitely.
The three most common leak paths:
.env that accidentally ends up inside a container image.Imagine putting your house key under the doormat labeled "spare key". That's an insecurely stored long-lived credential. The solution isn't storing it better — it's avoiding long-lived credentials entirely.
The modern solution to the problem above: temporary credentials — credentials that last a short time (usually 15 minutes to 12 hours), issued through an assumed role. If they leak, they expire on their own.
On AWS, the mechanism is STS AssumeRole: you request a temporary token to use a specific role.
aws sts assume-role \
--role-arn "arn:aws:iam::123456789012:role/DeployRole" \
--role-session-name "deploy-session" \
--duration-seconds 3600The command aws sts assume-role returns three values: access key, secret key, and session token — all valid for one hour. Example response:
{
"Credentials": {
"AccessKeyId": "ASIAEXAMPLEACCESSKEY",
"SecretAccessKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
"SessionToken": "IQoJb3JpZ2luX2IQoJb3JpZ2luX2IQoJb3JpZ2luEXAMPLE",
"Expiration": "2026-08-03T14:00:00Z"
},
"AssumedRoleUser": {
"AssumedRoleId": "AROEXAMPLEID:deploy-session",
"Arn": "arn:aws:sts::123456789012:assumed-role/DeployRole/deploy-session"
}
}These values are then used as session credentials:
export AWS_ACCESS_KEY_ID=ASIAEXAMPLEACCESSKEY
export AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
export AWS_SESSION_TOKEN=IQoJb3JpZ2luX2IQoJb3JpZ2luX2IQoJb3JpZ2luEXAMPLE
aws sts get-caller-identityNote: export AWS_SESSION_TOKEN=... uses environment variables, not code. In modern AWS SDKs, this mechanism is even automatic: processes running on EC2, ECS, or Lambda use an instance profile that assumes a role without needing to store a single static credential.
GCP uses the service account impersonation pattern: an identity (for example CI/CD) requests permission to "borrow" a specific service account's identity temporarily, and its credentials are issued as short-lived tokens.
gcloud auth application-default login \
--impersonate-service-account deploy-sa@my-project.iam.gserviceaccount.comThis approach avoids downloading service account keys (secret JSON files) that often leak — the impersonation credentials are issued on-demand and short-lived.
Azure uses managed identity and workload identity federation: applications running on Azure automatically get an identity managed by the platform, without any secrets at all. For CI/CD, federation connects a workload identity (for example GitHub Actions) directly to an Azure service principal — so no secrets need to be stored in the pipeline.
az ad app federated-credential create \
--id 00000000-0000-0000-0000-000000000000 \
--parameters parameters.jsonAll three providers' patterns share the same essence: don't store long-lived credentials — borrow an identity and keep its lifetime short.
Temporary credentials reduce risk, but no system is perfect. The final question you must always be able to answer is: who did what, and when? That's the job of audit logging.
| Provider | Audit Service | Example Events Recorded |
|---|---|---|
| AWS | AWS CloudTrail | sts assume-role, IAM changes, console logins |
| GCP | Cloud Audit Logs | Service account key creation, IAM changes |
| Azure | Activity Log | Role grants, resource creation, policy changes |
The audit log is the "black box" of a cloud account: it records every API call, by whom, from which IP, and with what result. With these logs, incidents can be traced, and bad practices like root account usage can be detected.
aws cloudtrail lookup-events \
--lookup-attributes AttributeKey=EventName,AttributeValue=AssumeRoleThe command aws cloudtrail lookup-events searches for the trail of who assumed a role and when. Recommended habit: enable audit logging from day one — not when a problem has already occurred.
.env that gets deployed.Episode 4 closes this series' basic security block:
In episode 5, you enter the backbone of cloud infrastructure: Virtual Private Cloud & networking — public and private subnets, gateways, and how to connect cloud resources securely.