diff --git a/builtin/credential/github/path_config.go b/builtin/credential/github/path_config.go index 84c03d3dbb79..707115c567e3 100644 --- a/builtin/credential/github/path_config.go +++ b/builtin/credential/github/path_config.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "net/url" + "os" "strings" "time" @@ -94,7 +95,8 @@ func (b *backend) pathConfigWrite(ctx context.Context, req *logical.Request, dat } if c.OrganizationID == 0 { - client, err := b.Client("") + githubToken := os.Getenv("VAULT_AUTH_CONFIG_GITHUB_TOKEN") + client, err := b.Client(githubToken) if err != nil { return nil, err } diff --git a/builtin/credential/github/path_config_test.go b/builtin/credential/github/path_config_test.go index e8d0cf5fdb39..d59599f32620 100644 --- a/builtin/credential/github/path_config_test.go +++ b/builtin/credential/github/path_config_test.go @@ -6,6 +6,7 @@ import ( "fmt" "net/http" "net/http/httptest" + "os" "strings" "testing" @@ -120,6 +121,43 @@ func TestGitHub_WriteReadConfig_OrgID(t *testing.T) { assert.Equal(t, "foo-org", resp.Data["organization"]) } +// TestGitHub_WriteReadConfig_Token tests that we can successfully read and +// write the github auth config with a token environment variable +func TestGitHub_WriteReadConfig_Token(t *testing.T) { + b, s := createBackendWithStorage(t) + // use a test server to return our mock GH org info + ts := setupTestServer(t) + defer ts.Close() + + err := os.Setenv("VAULT_AUTH_CONFIG_GITHUB_TOKEN", "foobar") + assert.NoError(t, err) + + resp, err := b.HandleRequest(context.Background(), &logical.Request{ + Path: "config", + Operation: logical.UpdateOperation, + Data: map[string]interface{}{ + "organization": "foo-org", + "base_url": ts.URL, // base_url will call the test server + }, + Storage: s, + }) + assert.NoError(t, err) + assert.Nil(t, resp) + assert.NoError(t, resp.Error()) + + // Read the config + resp, err = b.HandleRequest(context.Background(), &logical.Request{ + Path: "config", + Operation: logical.ReadOperation, + Storage: s, + }) + assert.NoError(t, err) + assert.NoError(t, resp.Error()) + + // the token should not be returned in the read config response. + assert.Nil(t, resp.Data["token"]) +} + // TestGitHub_ErrorNoOrgID tests that an error is returned when we cannot fetch // the org ID for the given org name func TestGitHub_ErrorNoOrgID(t *testing.T) { diff --git a/changelog/19244.txt b/changelog/19244.txt new file mode 100644 index 000000000000..63a663e9d6e4 --- /dev/null +++ b/changelog/19244.txt @@ -0,0 +1,4 @@ +```release-note:improvement +auth/github: Allow for an optional Github auth token environment variable to make authenticated requests when fetching org id +website/docs: Add docs for `VAULT_AUTH_CONFIG_GITHUB_TOKEN` environment variable when writing Github config +``` diff --git a/website/content/api-docs/auth/github.mdx b/website/content/api-docs/auth/github.mdx index 289fc736029a..6a83123e0258 100644 --- a/website/content/api-docs/auth/github.mdx +++ b/website/content/api-docs/auth/github.mdx @@ -32,6 +32,12 @@ distinction between the `create` and `update` capabilities inside ACL policies. - `base_url` `(string: "")` - The API endpoint to use. Useful if you are running GitHub Enterprise or an API-compatible authentication server. +### Environment variables +- `VAULT_AUTH_CONFIG_GITHUB_TOKEN` `(string: "")` - An optional GitHub token used to make + authenticated GitHub API requests. This can be useful for bypassing GitHub's + rate-limiting during automation flows when the `organization_id` is not provided. + We encourage you to provide the `organization_id` instead of relying on this environment variable. + @include 'tokenfields.mdx' ### Sample Payload