CCAS study materials
CCAS study resources

Contractor Access and the Orphaned OAuth Token

CCAS · Put your knowledge to work in context.

All case studies

Contractor Access and the Orphaned OAuth Token

A fintech has 600 employees and 80 contractors. Workforce identity is in Okta; AWS access is through IAM Identity Center with permission sets; production is in three AWS accounts. Contractors are currently added to Okta groups that map to broad ReadOnlyAccess and sometimes PowerUserAccess for 90-day engagements. CI/CD runs on GitHub Actions using long-lived IAM user access keys stored as repository secrets. Last month a contractor's laptop was compromised; the contractor had a personal OAuth token for a BI SaaS tool that could read production data exports. The token remained valid after the contractor's Okta account was disabled because the SaaS tool used a local account. Security wants to eliminate standing access and reduce blast radius without blocking engineering velocity.

1. Design the joiner-mover-leaver flow for contractors, including the SaaS OAuth token gap, and identify where Okta lifecycle events do not propagate.

Read the worked answer

Design: treat contractor lifecycle as a time-bound entitlement, not permanent group membership.

  1. Joiner: contractor record in Okta with a contractor profile and end date. Access is requested through an approval workflow that grants a time-bound entitlement, for example 30 days, to a contractor-specific AWS permission set and to SaaS apps. No standing PowerUserAccess.
  2. Mover: any change in engagement or scope triggers re-approval; Okta group membership alone should not grant production access.
  3. Leaver: Okta deactivation must trigger SCIM deprovisioning to SaaS apps and removal of IAM Identity Center assignments. For SaaS apps without SCIM, run a daily reconciliation and revoke sessions/tokens via the admin API.

The OAuth gap: disabling Okta does not revoke a token issued by a SaaS tool's local account. Inventory every SaaS app that can hold local credentials, require SSO-only where possible, disable local accounts, and use token revocation endpoints. For BI exports, replace standing OAuth tokens with short-lived delegated access or a team-owned service account, not an individual's token.

Where propagation fails: apps without SCIM, personal OAuth grants, API keys, and long-lived AWS keys. Add a weekly access review comparing Okta active users to each app's active principals.

2. Evaluate replacing GitHub Actions long-lived IAM keys with OIDC federation to AWS, including trust policy conditions and failure modes.

Read the worked answer

Replace long-lived keys with GitHub OIDC federation. Create an IAM OIDC identity provider for token.actions.githubusercontent.com and an IAM role whose trust policy restricts the subject to the exact repository and branch or tag, for example repo:org/repo:ref:refs/heads/main, and the audience to sts.amazonaws.com. The workflow requests a short-lived token with id-token: write and assumes the role.

Conditions: pin the subject to protected branches or GitHub environments; require environment approvals for production; scope the role to minimum actions; use separate roles per environment; set a short maximum session duration; deny role chaining to other roles.

Failure modes:

  • A workflow on an unprotected branch or from a fork can request a token if the trust policy is too broad; branch protection and subject conditions are the control.
  • A compromised repository maintainer can change the workflow to assume the role; require code review and environment protection.
  • OIDC provider misconfiguration or audience mismatch breaks deploys; test in non-production.
  • The role can still be over-privileged; pair with permissions boundaries and SCPs.

This removes stored AWS secrets but does not remove the need to protect the CI system itself.

3. What detection logic would you add to catch orphaned access after termination?

Read the worked answer

Detection logic:

  1. Identity correlation: join Okta user status (deactivated or suspended) to IAM Identity Center assignments and to CloudTrail userIdentity events for the last 90 days; alert on any event after deactivation.
  2. SaaS token telemetry: ingest SaaS audit logs and alert on local-account logins or OAuth token use by a user who is inactive in Okta, especially from a new ASN or country.
  3. AWS key usage: alert on AccessKeyLastUsed for IAM users tied to terminated contractors; block and rotate any key not used in 30 days.
  4. Access reviews: monthly manager attestation for contractor entitlements, with automatic revocation if not attested.
  5. Behavioral baseline: flag token use outside the contractor's normal hours or ASN, and impossible travel between SSO and SaaS.

Response: disable the identity in every downstream app, revoke OAuth grants and sessions, rotate shared secrets, and open an incident if data access occurred. The key gap is that Okta is not the sole source of truth; treat SaaS local accounts as a separate inventory.