Study guide

Sign-in and authentication: SSO, OAuth, OIDC and friends.

Who you are, what you may do, and how the standards fit together, ending with GitHub Actions signing in to AWS without stored keys.

Resumo (TL;DR)Summary (TL;DR)

Onde esta nota se encaixa: é o mapa de conceitos de identidade e acesso. Sessões, cookies e JWT do lado de quem constrói o app estão na nota de apps web seguros; o passo a passo completo do deploy está em GitHub para AWS com OIDC; o panorama da área, na trilha de cibersegurança.Where this note fits: it is the concept map for identity and access. Sessions, cookies and JWT from the app builder’s side are in the secure web apps note; the full deploy walkthrough is in GitHub to AWS with OIDC; the big picture of the field is in the cybersecurity path.
  1. Autenticar é provar quem você é; autorizar é decidir o que você pode fazer. São perguntas diferentes e protocolos diferentes.Authenticating is proving who you are; authorizing is deciding what you may do. They are different questions with different protocols.
  2. OAuth 2.0 cuida de autorização (tokens com escopo); OIDC e SAML cuidam de autenticação; SSO é a experiência de entrar uma vez só; MFA reforça a prova de identidade.OAuth 2.0 handles authorization (scoped tokens); OIDC and SAML handle authentication; SSO is the log-in-once experience; MFA strengthens the proof of identity.
  3. Em CI/CD, use OIDC para o GitHub Actions entrar na AWS com credenciais temporárias, sem chaves de acesso fixas guardadas em secrets.In CI/CD, use OIDC so GitHub Actions signs in to AWS with temporary credentials, with no fixed access keys stored in secrets.

Autenticação vs. autorizaçãoAuthentication vs. authorization

Dois conceitos que parecem um só e são a fonte da maior parte da confusão nesta área.Two concepts that look like one and cause most of the confusion in this area.

PerguntaQuestionNomeNameExemploExample
Quem é você?Who are you?Autenticação (AuthN)Authentication (AuthN)Senha + código do app autenticadorPassword + authenticator-app code
O que você pode fazer?What may you do?Autorização (AuthZ)Authorization (AuthZ)Pode ler o bucket, mas não apagarMay read the bucket, but not delete it
Analogia do hotel. Na recepção você mostra o documento (autenticação). Em troca, recebe um cartão que abre só o seu quarto e a academia, não os outros quartos (autorização). O cartão não diz o seu nome; só diz o que abre.Hotel analogy. At the front desk you show your ID (authentication). In return you get a key card that opens only your room and the gym, not the other rooms (authorization). The card does not say your name; it only says what it opens.

A ordem importa: primeiro se autentica, depois se autoriza. Um sistema que autoriza sem autenticar libera acesso para qualquer um; um que autentica sem autorizar deixa todo mundo logado ver tudo.Order matters: authenticate first, then authorize. A system that authorizes without authenticating gives access to anyone; one that authenticates without authorizing lets every logged-in user see everything.

Regra para o resto da nota: toda vez que aparecer OAuth, lembre que ele é sobre autorização (delegar acesso com um token). Saber quem é o usuário é trabalho do OpenID Connect, que roda por cima do OAuth.Rule for the rest of the note: whenever OAuth appears, remember it is about authorization (delegating access with a token). Knowing who the user is is the job of OpenID Connect, which runs on top of OAuth.

Formas de provar identidadeWays to prove identity

Os métodos se agrupam em três tipos de fator: algo que você sabe, algo que você tem e algo que você é.Methods fall into three kinds of factor: something you know, something you have and something you are.

MétodoMethodFatorFactorComo funcionaHow it worksPonto de atençãoWatch out for
SenhaPasswordSabeKnowSegredo compartilhado: você e o servidor conhecem o mesmo valor (o servidor guarda um hash).Shared secret: you and the server know the same value (the server stores a hash).Reuso, vazamento e phishing. Sozinha é o elo mais fraco.Reuse, leaks and phishing. Alone, it is the weakest link.
MFA / 2FAMFA / 2FACombina fatoresCombines factorsExige dois ou mais fatores de tipos diferentes (MFA = múltiplos; 2FA = exatamente dois). Ex.: senha + código TOTP (RFC 6238) ou chave de segurança.Requires two or more factors of different kinds (MFA = multiple; 2FA = exactly two). E.g. password + TOTP code (RFC 6238) or a security key.SMS é o mais fraco (troca de chip, interceptação). Prefira app autenticador ou chave física.SMS is the weakest (SIM swap, interception). Prefer an authenticator app or a hardware key.
PasswordlessPasswordlessTem / ÉHave / AreEntrar sem digitar senha: link ou código por e-mail, notificação no celular ou passkey.Signing in without typing a password: emailed link or code, phone prompt or passkey.Link e código por e-mail só são tão seguros quanto a caixa de e-mail.Emailed link and code are only as safe as the mailbox.
PasskeysPasskeysTem + (É ou Sabe)Have + (Are or Know)Par de chaves: a privada fica no seu dispositivo (ou no gerenciador de senhas), o site guarda só a pública. Você desbloqueia com biometria ou PIN do aparelho.Key pair: the private key stays on your device (or password manager), the site stores only the public one. You unlock with the device biometrics or PIN.Resistente a phishing, porque a credencial só funciona no domínio para o qual foi criada. Planeje a recuperação de conta.Phishing-resistant, because the credential only works on the domain it was created for. Plan account recovery.
BiometriaBiometricsÉAreImpressão digital, rosto. Em geral só desbloqueia uma chave guardada no aparelho; a digital não vai para o servidor.Fingerprint, face. It usually only unlocks a key stored on the device; the fingerprint is not sent to the server.Não dá para trocar uma digital vazada. Por isso costuma ser um desbloqueio local, não a credencial em si.You cannot replace a leaked fingerprint. That is why it is usually a local unlock, not the credential itself.

WebAuthn, FIDO2 e passkeys: quem é quemWebAuthn, FIDO2 and passkeys: who is who

  • WebAuthn: API do navegador (padrão do W3C) que cria e usa as credenciais de chave pública.WebAuthn: the browser API (a W3C standard) that creates and uses public-key credentials.
  • FIDO2: conjunto da FIDO Alliance formado por WebAuthn (navegador ↔ site) e CTAP (navegador ↔ chave de segurança).FIDO2: the FIDO Alliance set made of WebAuthn (browser ↔ site) and CTAP (browser ↔ security key).
  • Passkey: o nome amigável de uma credencial FIDO/WebAuthn, muitas vezes sincronizada entre os dispositivos do usuário.Passkey: the friendly name for a FIDO/WebAuthn credential, often synced across the user’s devices.

Protocolos e padrõesProtocols and standards

SSO: um conceito, não um protocoloSSO: a concept, not a protocol

Single Sign-On é a experiência de entrar uma vez e usar vários sistemas sem digitar a senha de novo. Não existe um “protocolo SSO”: ele é implementado com OIDC, SAML ou Kerberos. O que as apps têm em comum é confiar no mesmo provedor de identidade.Single Sign-On is the experience of signing in once and using several systems without typing the password again. There is no “SSO protocol”: it is implemented with OIDC, SAML or Kerberos. What the apps share is trusting the same identity provider.

OAuth 2.0 (autorização)OAuth 2.0 (authorization)

Framework (RFC 6749) para um app obter acesso limitado a algo seu sem receber a sua senha. É a analogia da chave de manobrista: ela liga o carro, mas não abre o porta-malas. O resultado é um access token com escopos.A framework (RFC 6749) for an app to get limited access to something of yours without receiving your password. Think of a valet key: it starts the car but does not open the trunk. The result is an access token with scopes.

OAuth é autorização, não autenticação. O access token diz “quem o carrega pode fazer X”; ele não é uma prova padronizada de quem é o usuário. Usar só OAuth para “fazer login” é um erro clássico: para isso existe o OIDC.OAuth is authorization, not authentication. The access token says “whoever holds it may do X”; it is not a standardized proof of who the user is. Using plain OAuth to “log in” is a classic mistake: that is what OIDC is for.
Fluxo (grant)Flow (grant)Quando usarWhen to use
Authorization Code + PKCEApps web, mobile e SPAs com usuário. É o recomendado hoje (PKCE: RFC 7636).Web, mobile and SPA apps with a user. The recommended one today (PKCE: RFC 7636).
Client CredentialsMáquina para máquina, sem usuário (um serviço chamando outro).Machine to machine, no user (one service calling another).
Device CodeTVs e CLIs, sem teclado confortável (RFC 8628).TVs and CLIs, without a comfortable keyboard (RFC 8628).
Implicit e PasswordEvite: são desencorajados pelas práticas atuais de segurança do OAuth (RFC 9700).Avoid: discouraged by current OAuth security practice (RFC 9700).

OpenID Connect, OIDC (autenticação)OpenID Connect, OIDC (authentication)

Camada de identidade sobre o OAuth 2.0. Acrescenta o escopo openid, o ID token (um JWT com claims sobre o usuário e sobre o login), o endpoint userinfo e um documento de descoberta em /.well-known/openid-configuration. Responde “quem é este usuário?”.An identity layer on top of OAuth 2.0. It adds the openid scope, the ID token (a JWT with claims about the user and the login), the userinfo endpoint and a discovery document at /.well-known/openid-configuration. It answers “who is this user?”.

SAML 2.0 (autenticação, mundo corporativo)SAML 2.0 (authentication, enterprise world)

Padrão mais antigo, baseado em XML. O provedor de identidade devolve uma assertion assinada ao app via navegador. Muito comum em ferramentas corporativas (SaaS B2B). Faz o mesmo papel do OIDC; apps novas costumam preferir OIDC por ser mais simples (JSON/JWT).An older standard based on XML. The identity provider returns a signed assertion to the app through the browser. Very common in enterprise tools (B2B SaaS). It plays the same role as OIDC; new apps usually prefer OIDC because it is simpler (JSON/JWT).

LDAP e Active DirectoryLDAP and Active Directory

LDAP (RFC 4511) é um protocolo para consultar e autenticar contra um diretório de usuários, grupos e dispositivos. Active Directory (AD) é o serviço de diretório da Microsoft, que fala LDAP e Kerberos; Microsoft Entra ID (antigo Azure AD) é a versão em nuvem, acessada com OIDC e SAML.LDAP (RFC 4511) is a protocol to query and authenticate against a directory of users, groups and devices. Active Directory (AD) is Microsoft’s directory service, which speaks LDAP and Kerberos; Microsoft Entra ID (formerly Azure AD) is the cloud version, reached with OIDC and SAML.

KerberosKerberos

Autenticação por tickets dentro de uma rede corporativa (RFC 4120). Você prova a identidade uma vez a um servidor central (o KDC) e recebe um ticket que as outras máquinas aceitam. É a base do “login do Windows que vale para tudo” em domínios AD.Authentication by tickets inside a corporate network (RFC 4120). You prove your identity once to a central server (the KDC) and get a ticket that other machines accept. It is the base of the “Windows login that works everywhere” in AD domains.

PadrãoStandardRespondeAnswersFormatoFormatOnde apareceWhere you see it
OAuth 2.0O que posso acessar?What may I access?Access tokenAPIs, “Permitir que o app acesse seu GitHub”APIs, “Allow the app to access your GitHub”
OIDCQuem é o usuário?Who is the user?ID token (JWT)“Entrar com Google”, GitHub Actions → AWS“Sign in with Google”, GitHub Actions → AWS
SAML 2.0Quem é o usuário?Who is the user?Assertion (XML)SaaS corporativo, SSO da empresaEnterprise SaaS, company SSO
LDAPQuem existe e em quais grupos?Who exists and in which groups?Consultas ao diretórioDirectory queriesServidores Linux, VPN, apps internasLinux servers, VPN, internal apps
KerberosQuem é o usuário na rede?Who is the user on the network?TicketsDomínio Windows/ADWindows/AD domain

GlossárioGlossary

TermoTermO que éWhat it is
IdP (Identity Provider)Quem autentica o usuário e emite a prova de identidade. Ex.: Google, Okta, Entra ID, e o GitHub Actions para os jobs.Who authenticates the user and issues the proof of identity. E.g. Google, Okta, Entra ID, and GitHub Actions for jobs.
SP / Relying Party (RP)O app que confia no IdP. “SP” (Service Provider) é o termo do SAML; “Relying Party” é o do OIDC. Na AWS, o papel de RP é do IAM/STS.The app that trusts the IdP. “SP” (Service Provider) is the SAML term; “Relying Party” is the OIDC one. In the GitHub-to-AWS case, AWS IAM/STS plays the RP.
TokenTexto que representa uma prova ou uma permissão, com prazo. Access token: autoriza chamar uma API. ID token: diz quem é o usuário. Refresh token: obtém novos access tokens.Text that represents a proof or a permission, with an expiry. Access token: authorizes calling an API. ID token: says who the user is. Refresh token: gets new access tokens.
JWT (JSON Web Token)Formato de token (RFC 7519): três partes em Base64URL separadas por ponto (cabeçalho, payload, assinatura). Fica assinado, não escondido: qualquer um lê o conteúdo, só quem tem a chave o forja.Token format (RFC 7519): three Base64URL parts separated by dots (header, payload, signature). It is signed, not hidden: anyone can read the content, only the key holder can forge it.
Sessão / cookieDepois do login, o app cria uma sessão e guarda um identificador num cookie. Os requests seguintes mostram o cookie em vez de pedir login de novo. Use HttpOnly, Secure e SameSite.After login, the app creates a session and stores an identifier in a cookie. Later requests show the cookie instead of asking for login again. Use HttpOnly, Secure and SameSite.
API keySegredo fixo que identifica um app ou projeto. Simples, mas não tem usuário, prazo nem escopo por padrão: se vazar, vale até alguém revogar.Fixed secret that identifies an app or project. Simple, but has no user, expiry or scope by default: if leaked, it works until someone revokes it.
RBAC (Role-Based Access Control)Autorização por papéis: você recebe um papel (ex.: deploy) e o papel concede as permissões. Na AWS, o equivalente são as roles do IAM.Authorization by roles: you get a role (e.g. deploy) and the role grants the permissions. On AWS, the equivalent is IAM roles.
Scope (escopo)Permissão pedida num token OAuth. Ex.: read:user, email, openid. O usuário vê e aprova na tela de consentimento.Permission requested in an OAuth token. E.g. read:user, email, openid. The user sees and approves it on the consent screen.
ClaimUma afirmação dentro do token: um par nome/valor. Ex.: sub (quem), iss (quem emitiu), aud (para quem), exp (quando expira).A statement inside the token: a name/value pair. E.g. sub (who), iss (who issued it), aud (for whom), exp (when it expires).

Fluxo completo: “Entrar com Google”Full flow: “Sign in with Google”

Usa OIDC sobre OAuth 2.0, com o fluxo Authorization Code + PKCE. O app é a Relying Party; o Google, o IdP.Uses OIDC on top of OAuth 2.0, with the Authorization Code + PKCE flow. The app is the Relying Party; Google is the IdP.

  1. O usuário clica em Entrar com Google no app.The user clicks Sign in with Google in the app.
  2. O app gera state (anti-CSRF), nonce (anti-replay do ID token) e um par PKCE (code_verifier secreto e code_challenge derivado).The app generates state (anti-CSRF), nonce (ID-token anti-replay) and a PKCE pair (secret code_verifier and derived code_challenge).
  3. O app redireciona o navegador para o endpoint de autorização do Google com client_id, redirect_uri, response_type=code, scope=openid email profile, state, nonce e code_challenge.The app redirects the browser to Google’s authorization endpoint with client_id, redirect_uri, response_type=code, scope=openid email profile, state, nonce and code_challenge.
  4. [Autenticação] O Google verifica quem é o usuário: senha, MFA ou passkey. Se já há sessão ativa no Google, é aqui que o SSO acontece e nada é digitado.[Authentication] Google checks who the user is: password, MFA or passkey. If there is already an active Google session, this is where SSO happens and nothing is typed.
  5. [Autorização] O Google mostra a tela de consentimento: “o app quer ver seu nome e e-mail”. O usuário aprova os escopos.[Authorization] Google shows the consent screen: “the app wants to see your name and email”. The user approves the scopes.
  6. O Google redireciona de volta ao redirect_uri com um code de uso único e o state.Google redirects back to the redirect_uri with a one-time code and the state.
  7. O app confere que o state é o mesmo que enviou. Se não for, aborta.The app checks that state is the one it sent. If not, it aborts.
  8. O backend do app troca o code por tokens no endpoint de token do Google, enviando também o code_verifier.The app’s backend exchanges the code for tokens at Google’s token endpoint, also sending the code_verifier.
  9. O Google devolve o ID token (JWT, diz quem é), o access token (autoriza chamar APIs do Google) e, às vezes, um refresh token.Google returns the ID token (JWT, says who it is), the access token (authorizes calling Google APIs) and, sometimes, a refresh token.
  10. O app valida o ID token: assinatura (chaves públicas do IdP), iss, aud igual ao seu client_id, exp e nonce.The app validates the ID token: signature (the IdP’s public keys), iss, aud equal to your client_id, exp and nonce.
  11. O app cria a sessão própria (cookie HttpOnly). A partir daí o Google já saiu de cena; o access token só é usado se o app precisar chamar APIs do Google.The app creates its own session (HttpOnly cookie). From then on Google is out of the picture; the access token is only used if the app needs to call Google APIs.
Os endpoints exatos (autorização, token, chaves públicas) estão no documento de descoberta do IdP. Para o Google, confira a documentação oficial de OpenID Connect.The exact endpoints (authorization, token, public keys) are in the IdP’s discovery document. For Google, check the official OpenID Connect documentation.

Regra de bolsoRule of thumb

  • OAuth 2.0 = autorização. “Este app pode acessar isto, com estes escopos.”OAuth 2.0 = authorization. “This app may access this, with these scopes.”
  • OIDC = autenticação, em cima do OAuth. “Este usuário é fulano.”OIDC = authentication, on top of OAuth. “This user is so-and-so.”
  • SAML = autenticação, com XML, no mundo corporativo.SAML = authentication, with XML, in the enterprise world.
  • SSO = experiência: entrar uma vez, usar várias apps. Implementado com OIDC, SAML ou Kerberos.SSO = experience: sign in once, use several apps. Implemented with OIDC, SAML or Kerberos.
  • MFA = reforço: mais de um fator para provar a identidade.MFA = reinforcement: more than one factor to prove identity.
  • JWT = formato do token, não um protocolo.JWT = the token format, not a protocol.
  • LDAP / AD = o diretório de usuários; Kerberos = tickets na rede interna.LDAP / AD = the user directory; Kerberos = tickets on the internal network.

Prática: OIDC no GitHub Actions → AWSPractice: OIDC from GitHub Actions → AWS

Aqui o “usuário” é um job de CI/CD. O GitHub é o IdP, a AWS é quem confia, e o resultado são credenciais temporárias no lugar de uma chave de acesso fixa (AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY) guardada em secrets. A troca de credenciais é autenticação (o token prova qual repositório e branch pediram) seguida de autorização (a role define o que pode ser feito).Here the “user” is a CI/CD job. GitHub is the IdP, AWS is the one that trusts it, and the result is temporary credentials instead of a fixed access key (AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY) stored in secrets. The exchange is authentication (the token proves which repository and branch asked) followed by authorization (the role defines what may be done).

Diagrama do fluxoFlow diagram

Job do ActionsActions job id-token: writeid-token: write GitHub OIDC (IdP)GitHub OIDC (IdP) emite o JWT assinadoissues the signed JWT AWS STS + IAMAWS STS + IAM role + trust policyrole + trust policy ECR / ECS / S3 ...ECR / ECS / S3 ... 1. pede o token1. asks for the token 2. JWT assinado2. signed JWT 3. AssumeRoleWithWebIdentity + JWT3. AssumeRoleWithWebIdentity + JWT 4. credenciais temporárias4. temporary credentials valida a assinaturaverifies the signature 5. usa as credenciais (expiram sozinhas)5. uses the credentials (they expire on their own)
O job nunca guarda segredo: o GitHub assina uma prova de identidade por execução e a AWS troca essa prova por credenciais de curta duração.The job never stores a secret: GitHub signs a proof of identity per run and AWS swaps that proof for short-lived credentials.

Passo 0: criar o provedor OIDC na AWS (uma vez por conta)Step 0: create the OIDC provider in AWS (once per account)

  • Provider URL: https://token.actions.githubusercontent.comProvider URL: https://token.actions.githubusercontent.com
  • Audience: sts.amazonaws.comAudience: sts.amazonaws.com

O passo a passo completo (console e CLI, duas contas, environments, secrets) está na nota GitHub para AWS com OIDC. Aqui ficam o mínimo e a teoria.The full walkthrough (console and CLI, two accounts, environments, secrets) is in the note GitHub to AWS with OIDC. Here you get the minimum and the theory.

Trust policy da role IAMIAM role trust policy

A trust policy diz quem pode assumir a role. As duas condições são o coração da segurança: aud garante que o token foi feito para a AWS e sub garante que veio do seu repositório e da sua branch.The trust policy says who may assume the role. The two conditions are the heart of the security: aud makes sure the token was meant for AWS and sub makes sure it came from your repository and your branch.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Federated": "arn:aws:iam::<ACCOUNT_ID>:oidc-provider/token.actions.githubusercontent.com"
      },
      "Action": "sts:AssumeRoleWithWebIdentity",
      "Condition": {
        "StringEquals": {
          "token.actions.githubusercontent.com:aud": "sts.amazonaws.com",
          "token.actions.githubusercontent.com:sub": "repo:<ORG>/<REPO>:ref:refs/heads/main"
        }
      }
    }
  ]
}
Nunca deixe o sub só com curinga. Sem ele restringido, outro repositório do GitHub poderia pedir a role. Se o job usa um environment, o sub muda para repo:ORG/REPO:environment:NOME. Repositórios novos podem usar um formato com IDs numéricos: confira os formatos atuais na documentação do GitHub.Never leave sub as just a wildcard. Without it restricted, another GitHub repository could request the role. If the job uses an environment, sub becomes repo:ORG/REPO:environment:NAME. New repositories may use a format with numeric IDs: check the current formats in the GitHub documentation.

Workflow do GitHub ActionsGitHub Actions workflow

name: deploy

on:
  push:
    branches: [main]

permissions:
  id-token: write   # lets the job request the OIDC token
  contents: read    # lets actions/checkout read the repo

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6

      - name: Configure AWS credentials (OIDC)
        uses: aws-actions/configure-aws-credentials@v6
        with:
          role-to-assume: arn:aws:iam::<ACCOUNT_ID>:role/github-deploy-main
          aws-region: sa-east-1

      - name: Who am I?
        run: aws sts get-caller-identity

Sem permissions: id-token: write o job não consegue pedir o token e a ação falha. A action configure-aws-credentials faz o passo 3 do diagrama e exporta as credenciais temporárias para os passos seguintes. Confira na página da action as versões e opções atuais.Without permissions: id-token: write the job cannot request the token and the action fails. The configure-aws-credentials action performs step 3 of the diagram and exports the temporary credentials to the following steps. Check the action’s page for current versions and options.

Claims do tokenToken claims

Esse é o payload de um token do GitHub (valores de exemplo). É isso que a AWS compara com a trust policy.This is the payload of a GitHub token (example values). This is what AWS compares against the trust policy.

{
  "iss": "https://token.actions.githubusercontent.com",
  "aud": "sts.amazonaws.com",
  "sub": "repo:<ORG>/<REPO>:ref:refs/heads/main",
  "repository": "<ORG>/<REPO>",
  "repository_owner": "<ORG>",
  "ref": "refs/heads/main",
  "sha": "<commit sha>",
  "workflow": "deploy",
  "event_name": "push",
  "actor": "<github user>",
  "job_workflow_ref": "<ORG>/<REPO>/.github/workflows/deploy.yml@refs/heads/main",
  "iat": 1760000000,
  "nbf": 1760000000,
  "exp": 1760003600
}
ClaimClaimSignificadoMeaningUso na segurançaUse in security
issQuem emitiu (o GitHub)Who issued it (GitHub)Identifica o provedor OIDC cadastrado na AWSIdentifies the OIDC provider registered in AWS
audPara quem o token foi feitoWho the token was made forCondição obrigatória: sts.amazonaws.comRequired condition: sts.amazonaws.com
subQuem pede: repositório + branch, tag, PR ou environmentWho is asking: repository + branch, tag, PR or environmentPrincipal condição de restriçãoMain restricting condition
repository, repository_ownerRepositório e donoRepository and ownerÚteis em políticas por organizaçãoUseful in organization-wide policies
ref, shaBranch/tag e commitBranch/tag and commitAuditoria: qual código rodouAudit: which code ran
job_workflow_refQual arquivo de workflow rodouWhich workflow file ranPermite amarrar a role a um workflow específico (verifique o suporte na documentação)Lets you tie the role to a specific workflow (check support in the documentation)
iat, nbf, expEmitido em, válido a partir de, expira emIssued at, not valid before, expires atO token é de curta duraçãoThe token is short-lived

Para ver os claims reais do seu job, decodifique o token em um passo de teste do workflow (o payload do JWT é Base64URL). Faça isso só em um repositório de teste, e não publique o token inteiro nos logs.To see the real claims of your job, decode the token in a test step of the workflow (the JWT payload is Base64URL). Do this only in a test repository, and do not publish the whole token in the logs.

Boas práticas de segurançaSecurity best practices

  • Uma role por ambiente (develop, production), cada uma com a sua trust policy e o mínimo de permissões (menor privilégio).One role per environment (develop, production), each with its own trust policy and minimum permissions (least privilege).
  • Restrinja o sub ao máximo: repositório e branch/environment exatos. Use StringEquals sempre que der.Restrict sub as much as possible: exact repository and branch/environment. Use StringEquals whenever you can.
  • Environments com aprovação para produção: o deploy só segue depois de um revisor aprovar.Environments with approval for production: the deploy only proceeds after a reviewer approves.
  • Permissões mínimas no workflow: declare permissions explicitamente em vez de herdar o padrão.Minimal workflow permissions: declare permissions explicitly instead of inheriting the default.
  • Cuidado com PRs de forks e com pull_request_target: não dê a role de deploy para código que você não revisou.Careful with fork PRs and pull_request_target: do not hand the deploy role to code you have not reviewed.
  • Fixe versões de actions de terceiros (por SHA do commit, quando possível), porque elas rodam no job que tem a role.Pin third-party action versions (by commit SHA when possible), because they run in the job that holds the role.
  • Remova as chaves antigas: depois de migrar, apague o usuário IAM e as chaves fixas que existiam.Remove the old keys: after migrating, delete the IAM user and the fixed keys that existed.
  • Audite: o CloudTrail registra AssumeRoleWithWebIdentity com o token usado; monitore usos inesperados.Audit: CloudTrail records AssumeRoleWithWebIdentity with the token used; monitor unexpected uses.

Erros comuns e como resolverCommon errors and how to fix them

SintomaSymptomCausa provávelLikely causeComo resolverHow to fix
Credentials could not be loaded / falha ao pegar o tokenFalta permissions: id-token: write (ou o permissions do workflow o removeu)Missing permissions: id-token: write (or the workflow permissions removed it)Adicione a permissão no workflow ou no jobAdd the permission to the workflow or job
Not authorized to perform sts:AssumeRoleWithWebIdentityO sub ou o aud do token não bate com a trust policyThe token’s sub or aud does not match the trust policyCompare os claims reais com a condição; confira branch × environment × PR e o formato do subCompare the real claims with the condition; check branch × environment × PR and the sub format
Funciona na main, falha no pull requestNo PR o sub é repo:ORG/REPO:pull_requestOn a PR, sub is repo:ORG/REPO:pull_requestUse uma role separada, de leitura, para PRs; não afrouxe a de deployUse a separate read-only role for PRs; do not loosen the deploy one
No OpenIDConnect provider found in your accountO provedor OIDC não existe na conta em que a role estáThe OIDC provider does not exist in the account that holds the roleCrie o provedor em cada conta que tem a roleCreate the provider in every account that has the role
Erro de audiência (aud)A condição espera outro valor que o do tokenThe condition expects a different value than the tokenUse sts.amazonaws.com nos dois lados, a menos que você tenha mudado a audience de propósitoUse sts.amazonaws.com on both sides, unless you changed the audience on purpose
redirect_uri_mismatch (OAuth/OIDC com Google etc.)A URL de retorno enviada difere da cadastrada no IdPThe return URL sent differs from the one registered at the IdPCadastre a URL exata (protocolo, domínio, caminho e barra final)Register the exact URL (scheme, domain, path and trailing slash)
invalid_grant na troca do codeCode expirado ou já usado, ou code_verifier não corresponde ao code_challengeCode expired or already used, or code_verifier does not match the code_challengeTroque o code uma única vez, logo após o retorno; guarde o verifier por sessãoExchange the code only once, right after the return; keep the verifier per session
Login em loop / sessão some após o retornoCookie de sessão bloqueado (SameSite, Secure em HTTP, domínio errado)Session cookie blocked (SameSite, Secure over HTTP, wrong domain)Revise os atributos do cookie e use HTTPSReview the cookie attributes and use HTTPS
Usar o access token para “saber quem é o usuário”Confusão entre autorização e autenticaçãoMixing up authorization and authenticationUse o ID token (OIDC), validado, para identidade; o access token é para chamar APIsUse the validated ID token (OIDC) for identity; the access token is for calling APIs
Aceitar um JWT sem validarSó decodificar o JWT não prova nada: qualquer um forja o payloadJust decoding a JWT proves nothing: anyone can forge the payloadValide assinatura, iss, aud e exp com uma biblioteca maduraValidate signature, iss, aud and exp with a mature library
Tokens guardados em localStorageQualquer XSS rouba o tokenAny XSS steals the tokenPrefira cookie HttpOnly para a sessãoPrefer an HttpOnly cookie for the session
Chave de acesso da AWS vazada em repositório ou logCredencial fixa sem prazoFixed credential with no expiryRevogue a chave agora, rode a auditoria no CloudTrail e migre para OIDCRevoke the key now, audit CloudTrail and migrate to OIDC

Cola e revisãoCheat sheet and review

ColaCheat sheet

Quero…I want…FaçaDo
entrar em apps sem digitar senha toda horasign in to apps without retyping the passworduse SSO (OIDC ou SAML) com um IdP centraluse SSO (OIDC or SAML) with a central IdP
proteger uma conta além da senhaprotect an account beyond the passwordMFA com app autenticador ou chave física; passkeys quando houver suporteMFA with an authenticator app or hardware key; passkeys where supported
saber quem é o usuário que entrouknow who the signed-in user isOIDC: valide o ID token (assinatura, iss, aud, exp, nonce)OIDC: validate the ID token (signature, iss, aud, exp, nonce)
dar a um app acesso limitado a uma APIgive an app limited access to an APIOAuth 2.0 Authorization Code + PKCE, com os menores escopos possíveisOAuth 2.0 Authorization Code + PKCE, with the smallest possible scopes
um serviço chamar outro, sem usuárioone service calling another, no userOAuth Client CredentialsOAuth Client Credentials
o GitHub Actions acessar a AWS sem chave fixaGitHub Actions to reach AWS with no fixed keyOIDC: provedor na AWS + role com trust policy em aud e sub + id-token: writeOIDC: provider in AWS + role with a trust policy on aud and sub + id-token: write
ver o que o token do job contémsee what the job’s token containsdecodifique o payload (Base64URL) num repositório de teste; nunca publique o token inteirodecode the payload (Base64URL) in a test repository; never publish the whole token

Perguntas de revisãoReview questions

PerguntaQuestionRespostaAnswer
Qual é a diferença entre autenticação e autorização, e por que o OAuth 2.0 sozinho não serve para “fazer login”?What is the difference between authentication and authorization, and why is plain OAuth 2.0 not meant for “logging in”?Autenticar prova quem você é; autorizar define o que você pode fazer. O OAuth entrega um access token (autorização), que não é uma prova padronizada de identidade; para isso existe o OIDC, com o ID token.Authenticating proves who you are; authorizing defines what you may do. OAuth delivers an access token (authorization), which is not a standardized proof of identity; that is what OIDC and the ID token are for.
No fluxo “Entrar com Google”, onde ocorre a autenticação, onde ocorre a autorização e o que o app faz com o ID token?In the “Sign in with Google” flow, where does authentication happen, where does authorization happen, and what does the app do with the ID token?A autenticação ocorre no Google (senha, MFA ou passkey); a autorização, na tela de consentimento dos escopos. O app valida o ID token e cria a própria sessão.Authentication happens at Google (password, MFA or passkey); authorization, at the scope consent screen. The app validates the ID token and creates its own session.
Na trust policy da role que o GitHub Actions assume, o que aud e sub protegem, e o que acontece se o sub estiver aberto demais?In the trust policy of the role GitHub Actions assumes, what do aud and sub protect, and what happens if sub is too open?aud garante que o token foi feito para a AWS; sub garante repositório e branch/environment. Aberto demais, outros repositórios ou branches conseguem assumir a role.aud makes sure the token was meant for AWS; sub pins the repository and branch/environment. Too open, other repositories or branches can assume the role.