Who can walk into your AWS account from outside?

Your scanner checks what is wrong inside the account. Almost nothing checks who is allowed to walk in.

Every cloud scanner looks at what is wrong inside an account. Very few show you the doors leading in: the OIDC providers, SAML federations and cross-account roles that let someone outside the account assume a role in it. Those trusts are configuration, not vulnerabilities, so they rarely appear in a findings list at all.

Yet each one is a standing permission for an outsider to become an insider. A CI system, a monitoring vendor, a contractor's account, another cloud. If you cannot list them, you cannot say who has access.

The doors into a cloud account

In AWS, every door is the same object: a trust policy on an IAM role, saying which principal may call sts:AssumeRole or one of its variants. The principal is what changes.

OIDC PROVIDERS
GitHub Actions, GitLab CI, Terraform Cloud, CircleCI and others mint short-lived tokens. A role that trusts the provider exchanges those tokens for AWS credentials through AssumeRoleWithWebIdentity. Conditions on the token's claims decide which pipeline gets in.
SAML FEDERATION
Your identity provider (Okta, Entra ID, Google Workspace) signs an assertion, and a role trusts that provider. Every user the IdP will sign for is a potential entrant.
CROSS-ACCOUNT ROLES
A trust policy names another AWS account, or a role inside it. Common between your own accounts, and common with vendors and contractors.
SAAS VENDOR ROLES
A special case of cross-account trust. A security, monitoring or cost tool asks every customer to create a role trusting the vendor's account, protected (if you followed the setup guide) by an sts:ExternalId.

Why scanners miss this

Nothing about a door looks broken. The trust policy is valid. The provider is registered correctly. The role works. A rule pack that asks "is there an OIDC provider?" gets the answer "yes" and moves on.

The question that matters is who the door admits, and that depends on conditions inside the policy. A role that trusts GitHub looks identical in an inventory whether it is pinned to one branch of one repository or open to every repository on GitHub. Only the Condition block tells them apart, and most tools do not parse it.

The second reason is reach. A door into a role with no permissions is harmless. A door into a role that can assume your deployment role is not. Seeing that means following the path after the door, which is the same graph problem described in what an attack path is.

The GitHub Actions wildcard problem

This is the best-known open door. Registering GitHub as an OIDC provider does not scope anything to your repositories. GitHub issues tokens to every repository on the platform. The only thing that narrows them is a condition on the sub claim.

Here is a trust condition that looks restrictive and is not:

"Condition": {
  "StringEquals": { "token.actions.githubusercontent.com:aud": "sts.amazonaws.com" }
}

The audience check proves the token was minted for AWS. It says nothing about which repository asked for it. Any GitHub user can create a repository, add a short workflow that requests a token, and assume this role. There is no exploit involved. The policy is doing exactly what it says.

The fix is one more line:

"Condition": {
  "StringEquals": {
    "token.actions.githubusercontent.com:aud": "sts.amazonaws.com",
    "token.actions.githubusercontent.com:sub": "repo:ACME/api:ref:refs/heads/main"
  }
}

Two softer versions of the same mistake are worth checking too. A subject of repo:ACME/* trusts every repository in the organisation, including ones created next month. A subject of repo:ACME/api:* trusts every branch and tag, so anyone who can push a branch can use the role. The frontdoor docs cover each one: no subject condition (FD001), org-wide subjects (FD010) and any branch or tag (FD011).

What an unused identity provider costs you

An OIDC or SAML provider that no role references looks harmless. It grants nothing on its own. The risk is quieter than that.

Anyone who can edit a trust policy can point a role at an existing provider without creating anything new. Reviewers see a provider that has been there for two years and assume it is in use. Registering a new provider is a visible event. Attaching to an old one is not.

This is what the check looks like on an account with a GitLab provider left behind from a migration:

  frontdoor 0.1.0  ·  acme-prod (111122223333)  ·  2026-10-03 09:12 UTC

  | MEDIUM  (1) ------------------------------------------------------------------

    FD021  Unused identity provider: gitlab.com
           arn:aws:iam::111122223333:oidc-provider/gitlab.com

           Wrong     This identity provider is registered but nothing references it.
           Attacker  Anyone who can write an IAM policy can point a role or service
                     account at this provider without creating anything that looks
                     new, and reviewers tend to assume a registered provider is in
                     use.
           Evidence  referenced by 0 roles or service accounts
           Fix       Delete the provider if the integration is gone.
                     - Confirm no role in any account in the organization uses it -
                     frontdoor only sees this account.
                     - Delete it with iam:DeleteOpenIDConnectProvider or
                     iam:DeleteSAMLProvider.
                     - Re-registering it later takes a minute; leaving it costs you
                     a blind spot.
           Docs      https://www.secorvia.com/docs/frontdoor/FD021

  No external identity can enter your cloud.
  1 finding: 1 medium.

The fix is a single CLI call, after you confirm that no account in the organisation still uses the provider. The full reasoning is on the FD021 rule page.

Trust types and what to check

Each kind of external trust in AWS, what goes wrong, and the condition that fixes it
Trust typeWhat goes wrongWhat to checkfrontdoor rule
GitHub Actions OIDCNo sub condition, so any repository on GitHub can assume the roleAn exact sub with StringEqualsFD001
GitHub Actions OIDCSubject pinned to the organisation onlyOne subject per repository and refFD010
Cross-account vendor roleNo sts:ExternalId, so another customer of the vendor can reach youThe ExternalId the vendor issued to youFD013
Cross-account roleTrusts an account nobody can identifyCloudTrail AssumeRole history for that accountFD014
OIDC or SAML providerRegistered but referenced by no roleWhether any account in the organisation uses itFD021

How to check your own account

We built frontdoor to answer this one question. It is a single binary, licensed under Apache 2.0, with no account and no signup. It uses the credentials you already have and makes only read calls.

go install github.com/secorvia/frontdoor/cmd/frontdoor@latest
frontdoor scan --aws

The AWS-managed SecurityAudit policy covers everything it reads. The report lists every external identity that can enter, what each one reaches, and the findings with a corrected Condition block built from your own issuer and repository names. Add --fail-on high to fail a CI job, or --format sarif to send findings to the GitHub Security tab.

It is safe to run against production. Every AWS call it makes is a List, Get or Describe. When a call is denied, the report says so, and the rules that depended on it lower their own severity rather than guess, so a partial scan never passes itself off as a clean one. That matters most in member accounts, where reading the Organization is often not allowed.

It also covers GCP workload identity federation and, in beta, Azure. When you scan AWS and GCP together it follows a path across the boundary, which neither cloud's own tooling shows. The frontdoor documentation lists all fifteen rules, and the cross-cloud rule explains how the two halves are joined.

What frontdoor does not do

It is deliberately narrow. It is not a CSPM, so it does not check bucket ACLs, security groups, encryption or compliance frameworks. It does not look for CVEs. It does not watch anything at runtime. It answers one question (who outside can get in, and how far do they get?) and stops. If you already run a broad scanner such as Prowler, run frontdoor alongside it rather than instead of it. If you are still choosing a full platform, our comparison of cloud security platforms sets out what each one covers.

Common misconceptions

"An audience condition restricts the role." It restricts which system the token was minted for, not who asked for it.

"Vendor roles are the vendor's problem." The trust policy is in your account. If it lacks an ExternalId, the confused deputy risk is yours.

"Old providers are inert." They are inert until someone attaches a role to them, and that change is easy to miss.

FAQ

How do I see which external identities can assume my AWS roles?

Read the trust policy of every IAM role and list each principal that is not a service. In practice that means OIDC providers, SAML providers and other AWS accounts. frontdoor does this in one command and also follows what each door can reach.

Is the aud condition enough for GitHub Actions OIDC?

No. The aud claim only shows the token was minted for AWS. Without a condition on sub, any repository on GitHub can assume the role.

Should I delete an unused OIDC provider?

Yes, once you have checked that no role in any account of the organisation references it. It grants nothing on its own, but it gives anyone who can edit a trust policy an easy door that reviewers will not notice.

What permissions does frontdoor need?

Read-only IAM, STS and Organizations calls. The AWS-managed SecurityAudit policy is a superset of what it uses, and it never writes anything.

Does frontdoor send data anywhere?

No. It has no telemetry and talks only to your cloud provider. The one optional network call, --resolve, opens a TLS handshake to an OIDC issuer to read its certificate chain and is off by default.

Is frontdoor a replacement for a CSPM?

No. It checks the trust into an account, not the configuration inside it. Use it alongside a CSPM or a broad scanner.

frontdoor is built by the team behind Secorvia, which runs the same analysis continuously across every connected account.

Keep reading
Identity · 6 min read

CIEM: the over-permissioned identity problem

Fundamentals · 6 min read

What is an attack path in cloud security?

Fundamentals · 7 min read

Blast radius: measuring what falls with a single asset

Want this checked continuously, across every account?