Skip to content

Conversation

@nickviola
Copy link
Contributor

@nickviola nickviola commented Nov 4, 2025

🗣 Description

Replace Cognito with custom SAML auth service provider logic to authenticate users and change primary linking user. attribute to OktaID instead of email address. See CRASM Ticket for detailed documentation for new endpoints and process breakdown.

Certificate and Metadata URL ENV vars for encrypted deployments will be added via new Django S3 logic process (CRASM-2599)

New SAML endpoints (See CRASM Ticket for detailed documentation):

  1. GET /saml/metadata
  2. GET /saml/login
  3. POST /saml/acs
  4. GET /saml/logout

New auth flowchart:

auth-flow

💭 Motivation and context

This removes the need for additional third party user pool configuration/management and decreases failure point surface for authentication. This will allow us to remove the third party Cognito dependency and keep authentication flow complletely in the backend with direct SAML authentication with Okta. This also allows us to control the user upsert process and primary linking keys (OktaID vs NameID/Email).

🧪 Testing

Authentication Flow from a UI perspective should not change, Locally, you will need to make sure you have the OKTA_METADATA_URL added to your local env. This URL will be shared with the team for testing.

✅ Pre-approval checklist

  • This PR has an informative and human-readable title.
  • Changes are limited to a single goal - eschew scope creep!
  • All future TODOs are captured in issues, which are referenced in code comments.
  • All relevant type-of-change labels have been added.
  • I have read the CONTRIBUTING document.
  • These code changes follow cisagov code standards.
  • All relevant repo and/or project documentation has been updated to reflect the changes in this PR.
  • Tests have been added and/or modified to cover the changes in this PR.
  • All new and existing tests pass.

@nickviola nickviola self-assigned this Nov 4, 2025
@nickviola nickviola marked this pull request as ready for review November 18, 2025 22:02
Copy link
Collaborator

@cduhn17 cduhn17 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See comments

ameliav

This comment was marked as outdated.

@nickviola
Copy link
Contributor Author

Known Frontend CI failures that are being addressed in other tickets:

Linter issues: https://maestro.dhs.gov/jira/browse/CRASM-3437
Logger syntax issue: https://maestro.dhs.gov/jira/browse/CRASM-3384
Regression Testing: https://maestro.dhs.gov/jira/browse/CRASM-3434

validate_json_serialization,
)

logging.basicConfig(level=logging.INFO)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there is already a basicConfig in settings.py. In practice, one basicConfig is desirable in Django, if you have more than one, can cause unexpected results.

raise RuntimeError("OKTA_SAML_METADATA_URL is not set")

# Fetch & parse IdP metadata
idp_data = _SamlConfig.idp_parser.parse_remote(OKTA_METADATA_URL)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Validate the URL before passing it into parse_remote. Wrap parse_remote in a try/except and log a clear error, then raise a controlled RuntimeError with a generic message, not the full stack trace or URL.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants