Skip to content

feat: add github_user_external_identity_by_saml data source#3268

Open
MegaportPhilipBrowne wants to merge 1 commit intointegrations:mainfrom
MegaportPhilipBrowne:feat/data-source-external-identity-by-saml
Open

feat: add github_user_external_identity_by_saml data source#3268
MegaportPhilipBrowne wants to merge 1 commit intointegrations:mainfrom
MegaportPhilipBrowne:feat/data-source-external-identity-by-saml

Conversation

@MegaportPhilipBrowne
Copy link

Description

Adds a new data source github_user_external_identity_by_saml that performs a reverse external identity lookup: given a SAML NameID (typically an email address), it returns the linked GitHub username.

This complements the existing github_user_external_identity data source, which looks up SAML/SCIM identity by GitHub username. The new data source enables the opposite direction — email-to-username resolution at terraform plan/apply time.

Motivation

When managing GitHub organization membership via Terraform (e.g. team memberships), it's common to know users by their corporate email address but not their GitHub username. The existing github_user_external_identity data source requires the GitHub username as input, which creates a chicken-and-egg problem.

This is particularly important for organizations that:

  • Manage team memberships in Terraform using identity data from an external source (e.g. Google Workspace, Workday)
  • Need every terraform plan to re-resolve the email-to-username mapping to avoid drift from GitHub username changes (which would be a security risk in SCIM-provisioned orgs)

Implementation

The implementation mirrors github_user_external_identity closely. The only material difference is the GraphQL query filter:

  • Existing: externalIdentities(first: 1, login: $username) — filters by GitHub login
  • New: externalIdentities(first: 1, userName: $userName) — filters by SAML NameID

The userName parameter is documented in GitHub's platform-samples and troubleshooting docs.

Example Usage

data "github_user_external_identity_by_saml" "user" {
  saml_name_id = "user@example.com"
}

resource "github_team_membership" "example" {
  team_id  = github_team.some_team.id
  username = data.github_user_external_identity_by_saml.user.login
}

Arguments

  • saml_name_id (Required) — The SAML NameID (typically email) to look up.

Attributes

  • login — The GitHub username linked to this SAML identity.
  • username — Same as login.
  • saml_identity — Map of SAML identity attributes (name_id, username, given_name, family_name).
  • scim_identity — Map of SCIM identity attributes (username, given_name, family_name).

Changes

  • github/data_source_github_user_external_identity_by_saml.go — New data source implementation
  • github/data_source_github_user_external_identity_by_saml_test.go — Acceptance test
  • github/provider.go — Register the new data source
  • website/docs/d/user_external_identity_by_saml.html.markdown — Documentation

Test Plan

  • go build ./... passes
  • go vet ./github/... passes
  • Acceptance test requires enterprise mode with SAML SSO configured

Add a new data source that performs a reverse external identity lookup:
given a SAML NameID (typically an email address), return the linked
GitHub username. This complements the existing
github_user_external_identity data source which looks up SAML/SCIM
identity by GitHub username.

The new data source uses the GraphQL externalIdentities endpoint with
the userName filter parameter instead of the login filter, enabling
email-to-username resolution at plan/apply time.
@github-actions
Copy link

👋 Hi! Thank you for this contribution! Just to let you know, our GitHub SDK team does a round of issue and PR reviews twice a week, every Monday and Friday! We have a process in place for prioritizing and responding to your input. Because you are a part of this community please feel free to comment, add to, or pick up any issues/PRs that are labeled with Status: Up for grabs. You & others like you are the reason all of this works! So thank you & happy coding! 🚀

@github-actions github-actions bot added the Type: Feature New feature or request label Mar 11, 2026
@deiga
Copy link
Collaborator

deiga commented Mar 12, 2026

Question: this could have been an additional field in the existing data source, right?
What made you consider creating a new one instead of extending the existing one?

@MegaportPhilipBrowne
Copy link
Author

Good question — yes, it could have been. The reasoning for a new data source was:

  1. Input semantics: the existing data source uses username as both a required input and as a computed output (aliasing login). Making it an optional input alongside a new saml_name_id input would muddy that contract.
  2. Single responsibility: each data source has one clear required input and a deterministic read path, avoiding mutual-exclusion validation logic (ExactlyOneOf) in the read function.

That said, I don't have a strong opinion on this — if you'd prefer a single extended data source with ExactlyOneOf: ["username", "saml_name_id"] and username made optional, I'm happy to rework it that way. It would reduce the surface area of the provider by one data source, which seems like a reasonable trade-off.

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

Labels

Type: Feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants