Skip to content

feat: add auth_mode for explicit auth configuration#3246

Open
laughedelic wants to merge 11 commits intointegrations:mainfrom
laughedelic:feat/auth-mode-rework
Open

feat: add auth_mode for explicit auth configuration#3246
laughedelic wants to merge 11 commits intointegrations:mainfrom
laughedelic:feat/auth-mode-rework

Conversation

@laughedelic
Copy link
Contributor

@laughedelic laughedelic commented Mar 2, 2026

This PR


Before the change?

After the change?

Based on the proposal in #3116:

  • New auth_mode argument enables explicit control over authentication:
    • auth_mode = "anonymous" ignores any credentials
    • auth_mode = "token" errors if no token is provided instead of silently falling back
    • auth_mode = "app" errors if app credentials are missing or incomplete
    • When auth_mode is not set, the existing auto-detection behavior is preserved (backward compatible)
  • New top-level app_id, app_installation_id, app_private_key arguments allow app auth without the app_auth block, making it possible to switch between token and app auth purely via environment variables (addressing [FEAT]: Switching Between PAT and GitHub App Authentication Without Modifying Terraform Code #1877)
  • app_auth block is deprecated with a mention of the new top-level arguments
  • gh auth token CLI fallback is deprecated (as proposed in [MAINT]: Rework provider auth configuration #3116)

Note, I took the liberty to name the new top-level argument app_private_key instead of app_pem_file because I believe it is more clear that the expected value is a private key content, not a file reference. I remember there was this old comment:

I feel like the naming of the pem_file argument in app_auth is a little confusing because it expects the content of the file, not its path. Maybe calling it private_key would have been clearer


Pull request checklist

  • Schema migrations have been created if needed (example)
  • Tests for the changes have been added (for bug fixes / features)
  • Docs have been reviewed and added / updated if needed (for bug fixes / features)

Does this introduce a breaking change?

  • No

I didn't implement environment_variable_prefix and auth_type from the #3116's proposal to keep this focused, and implementing those seemed like touching many more places. But I can add those separately.

@github-actions
Copy link

github-actions bot commented Mar 2, 2026

👋 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 2, 2026
@laughedelic
Copy link
Contributor Author

laughedelic commented Mar 2, 2026

Thinking some more about the auth_mode and the empty default with some auto-resolution for compatibility: what if it was a priority list instead of a single value? This would allow users to set their own fallback logic by saying auth_mode = ["app", "cli", "token"] and depending on the environment, it would use different options in that order. WDYT?

UPD: Maybe I'm just overcomplicating it. Feel free to ignore this.

Copy link
Collaborator

@deiga deiga left a comment

Choose a reason for hiding this comment

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

I think this is looking great!

I've been wanting to get to this for a while now 😬

Left a few minor comments

var appID, appInstallationID, appPemFile string
switch authMode {
case "anonymous":
log.Printf("[INFO] Auth mode: anonymous")
Copy link
Collaborator

Choose a reason for hiding this comment

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

Could you test if we can use tflog inside this func?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Seems to be fine. Done in e07604b.

case "token":
token = d.Get("token").(string)
if token == "" {
return nil, diag.FromErr(fmt.Errorf(
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
return nil, diag.FromErr(fmt.Errorf(
return nil, diag.Errorf(

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done in c33ccb5

Comment on lines +133 to +151
"app_id": {
Type: schema.TypeString,
Optional: true,
DefaultFunc: schema.EnvDefaultFunc("GITHUB_APP_ID", nil),
Description: descriptions["app_id"],
},
"app_installation_id": {
Type: schema.TypeString,
Optional: true,
DefaultFunc: schema.EnvDefaultFunc("GITHUB_APP_INSTALLATION_ID", nil),
Description: descriptions["app_installation_id"],
},
"app_private_key": {
Type: schema.TypeString,
Optional: true,
Sensitive: true,
DefaultFunc: schema.EnvDefaultFunc("GITHUB_APP_PRIVATE_KEY", nil),
Description: descriptions["app_private_key"],
},
Copy link
Collaborator

Choose a reason for hiding this comment

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

Could you add ConflictsWith fields so that it's not possible to set both App auth configs at the same time? Or does that interfere with the DefaultFunc being the same?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't think it interferes with the default value, but it probably doesn't raise the conflict when everything is set through env vars. In any case, I added mutually exclusive ConflictsWith in e3264c4. And further validation is done in providerConfigure.

})
})

t.Run("can be configured with top-level app fields without auth_mode", func(t *testing.T) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Hmm, I would prefer if this wouldn't be possible. Can we force setting of auth_mode for top-level app fields? Or are we limited by backwards compatibility?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is a bit more involved than just requiring auth_mode = app if the top-lvel app fields are set. I added an extra validation in the "default" case, to make sure that if the top-level fields are set and there is no app_auth block, we get an error about setting auth_mode.
There are cases when user can set both the token and the app values, but then choose which set of credentials to use via auth_mode. Any or all of them can be set via env vars. So I think this shouldn't be too strict.
See af6fb59. I added some extra tests for the edge cases. Let me know if we're on the same page.

@laughedelic laughedelic requested a review from deiga March 5, 2026 03:14
Copy link
Collaborator

@deiga deiga left a comment

Choose a reason for hiding this comment

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

Whoo! This seems so much simpler than what I had thought it would be 😬

I hope we're not missing something

@deiga deiga requested a review from stevehipwell March 5, 2026 22:45
@laughedelic
Copy link
Contributor Author

@stevehipwell could you give some feedback here?

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

2 participants