Skip to content

GODRIVER-2806: Implement automatic GCP token acquisition #1708

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 80 commits into from
Jul 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
80 commits
Select commit Hold shift + click to select a range
a47681f
GODRIVER-2911: Initial attempted to untie the Gordian not, this will …
pmeredit Jun 11, 2024
279635a
GODRIVER-2911: We're going to have to go this way and implement some …
pmeredit Jun 12, 2024
9170d50
GODRIVER-2911: Ok, not great, but this will work
pmeredit Jun 12, 2024
590662d
GODRIVER-2911: Renaming oidc sasl
pmeredit Jun 12, 2024
171204c
GODRIVER-2911: Implement Operation based private sasl conversation fo…
pmeredit Jun 12, 2024
dbc5699
GODRIVER-2911: Privitize all the oidc sasl api, move AuthConfig up so…
pmeredit Jun 12, 2024
ff73302
GODRIVER-2911: Move things as necessary for authentication registration
pmeredit Jun 12, 2024
0db7c3e
GODRIVER-2911: Let's use a bit better naming
pmeredit Jun 12, 2024
be99139
GODRIVER-2911: Add Reauth to Authenticators
pmeredit Jun 12, 2024
f400d18
GODRIVER-2911: Check point
pmeredit Jun 12, 2024
eed3dd5
GODRIVER-2911: Initial plumbing, the Client Authenticator is going to…
pmeredit Jun 13, 2024
2ee93cc
GODRIVER-2911: Set authenticator in topology
pmeredit Jun 13, 2024
f6def8d
GODRIVER-2911: Set authenticator from Command to Operation
pmeredit Jun 13, 2024
bd5c9f2
GODRIVER-2911: Remove authenticator so we can readd it programmatically
pmeredit Jun 13, 2024
36ba008
GODRIVER-2911: Remove authenticator so we can readd it programmatically
pmeredit Jun 13, 2024
a2a4029
GODRIVER-2911: Remove authenticator so we can readd it programatically
pmeredit Jun 13, 2024
d2c75f1
GODRIVER-2911: Add all that authenticator plumbing programmatically s…
pmeredit Jun 13, 2024
4070d06
GODRIVER-2911: Thread through Authenticator
pmeredit Jun 13, 2024
4a44090
GODRIVER-2911: Move OIDC back to auth package, yay
pmeredit Jun 14, 2024
4ea9b9c
GODRIVER-2911: Move Config = AuthConfig to top of the file
pmeredit Jun 14, 2024
2b5cde6
GODRIVER-2911: Update comment
pmeredit Jun 14, 2024
368cedd
GODRIVER-2911: Some implementation
pmeredit Jun 14, 2024
e00e057
GODRIVER-2911: Add OIDCTokenGenID to Connection interface
pmeredit Jun 14, 2024
1666c6c
GODRIVER-2911: Add OIDCTokenGenID to Connection interface for types i…
pmeredit Jun 14, 2024
d90ee3f
GODRIVER-2911: Actually add the oidc file, whoops
pmeredit Jun 14, 2024
19ed261
GODRIVER-2911: Fix nil pointer error
pmeredit Jun 14, 2024
4112208
GODRIVER-2911: Fix fmt
pmeredit Jun 14, 2024
03c4c08
GODRIVER-2911: Fix build failure
pmeredit Jun 14, 2024
dac0468
GODRIVER-2911: well, that was silly
pmeredit Jun 14, 2024
651af66
GODRIVER-2911: Add licenses and fix comment
pmeredit Jun 14, 2024
6b16e91
GODRIVER-2911: Fix receiver names and remove authenticator field from…
pmeredit Jun 14, 2024
26412ae
GODRIVER-2911: Fix many lints. Linter not running for me locally
pmeredit Jun 14, 2024
98e8cbe
GODRIVER-2911: Fix lints
pmeredit Jun 15, 2024
78fa217
GODRIVER-2911: Fix spelling error
pmeredit Jun 15, 2024
46fa6f3
GODRIVER-2911: Testing checkpoint
pmeredit Jun 18, 2024
c6d23de
GODRIVER-2911: Fix config, fix spec auth
pmeredit Jun 18, 2024
c137399
GODRIVER-2911: Checkpoint
pmeredit Jun 19, 2024
1be9498
GODRIVER-2911: OIDC working
pmeredit Jun 19, 2024
8542f76
GODRIVER-2911: add machine_1_2
pmeredit Jun 19, 2024
286525f
GODRIVER-2911: add machine_1_2, actually helps to call it
pmeredit Jun 19, 2024
4013ccb
GODRIVER-2911: Remove unneeded debugging
pmeredit Jun 19, 2024
83ffaa7
GODRIVER-2911: Add more tests
pmeredit Jun 20, 2024
f33dca7
GODRIVER-2911: Updates
pmeredit Jun 20, 2024
3c00307
GODRIVER-2911: Change to using errors
pmeredit Jun 20, 2024
590a3c8
GODRIVER-2911: Add more tests that do not require fail points
pmeredit Jun 20, 2024
e88ebe7
GODRIVER-2911: See if it fails with 10 tries
pmeredit Jun 20, 2024
58f0f42
GODRIVER-2911: Not sure how to get fail points working
pmeredit Jun 20, 2024
1be1e13
GODRIVER-2911: Appease linter
pmeredit Jun 20, 2024
6e1fd3a
GODRIVER-2911: Appease linter
pmeredit Jun 20, 2024
640907d
GODRIVER-2911: Change 3_3 to use fail on find, add 4_1
pmeredit Jun 21, 2024
4d30705
GODRIVER-2911: Manually create fail points
pmeredit Jun 23, 2024
9dd40c9
GODRIVER-2911: This is working except 3_3 seems to be hanging
pmeredit Jun 23, 2024
b343ebb
GODRIVER-2911: Tests all passing
pmeredit Jun 23, 2024
5240a91
GODRIVER-2911: Appease linter
pmeredit Jun 23, 2024
0cdd7a2
GODRIVER-2911: Remove test func that is unneeded
pmeredit Jun 23, 2024
4613c5f
Update x/mongo/driver/auth/oidc.go
pmeredit Jun 26, 2024
40998b6
SQL-1937: Remove spurious authenticators, move mutex
pmeredit Jun 26, 2024
2d09cc5
SQL-1937: Change Reauth interface
pmeredit Jun 26, 2024
d45c7e4
Update Makefile
pmeredit Jul 1, 2024
ae9c34f
GODRIVER-2911: Apply httpclient patch
pmeredit Jul 1, 2024
1d86914
GODRIVER-2911: Fix races
pmeredit Jul 1, 2024
30ed4c4
GODRIVER-2911: Back out changes to sasl, add comment, remove Println …
pmeredit Jul 2, 2024
519205c
GODRIVER-2911: Move public OIDC configuration types into public, non-…
pmeredit Jul 2, 2024
5f0c68d
GODRIVER-2911: Improve comment
pmeredit Jul 2, 2024
6410109
GODRIVER-2728: Add azurecallback support
pmeredit Jul 3, 2024
7dc89cb
GODRIVER-2728: Update test framework
pmeredit Jul 3, 2024
b84cc12
GODRIVER-2728: No idea what this incredibly unhelpful shellscript fai…
pmeredit Jul 3, 2024
6a3af5a
GODRIVER-2911: Update script comment
pmeredit Jul 3, 2024
386389d
GODRIVER-2728: cp
pmeredit Jul 4, 2024
7340ddd
GODRIVER-2911: Use conversion functions instead of type redeclarations
pmeredit Jul 4, 2024
902bb9b
Merge branch 'GODRIVER-2911' into GODRIVER-2728
pmeredit Jul 8, 2024
e86b80b
GODRIVER-2728: Appears to be working once I can figure out the json side
pmeredit Jul 8, 2024
9878c73
GODRIVER-2728: Should work now
pmeredit Jul 8, 2024
aa887de
GODRIVER-2728: Working, remove debugging
pmeredit Jul 8, 2024
39d045b
GODRIVER-2728: Cleanup
pmeredit Jul 8, 2024
509fc2a
GODRIVER-2806: GCP
pmeredit Jul 9, 2024
f670f4b
GODRIVER-2806: Fix test name
pmeredit Jul 9, 2024
75723db
GODRIVER-2806: Implement GCP automatic token acquisition
pmeredit Jul 22, 2024
0e9eadc
Make gcp error messaging consistent with Azure
pmeredit Jul 23, 2024
db713c6
Merge branch 'v1' into GODRIVER-2806
pmeredit Jul 24, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 51 additions & 0 deletions .evergreen/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2000,6 +2000,31 @@ tasks:
export AZUREOIDC_TEST_CMD="PROJECT_DIRECTORY='.' OIDC_ENV=azure OIDC=oidc ./etc/run-oidc-test.sh ./test"
bash $DRIVERS_TOOLS/.evergreen/auth_oidc/azure/run-driver-test.sh

- name: "oidc-auth-test-gcp-latest"
commands:
- command: shell.exec
params:
working_dir: src/go.mongodb.org/mongo-driver
shell: bash
script: |-
set -o errexit
${PREPARE_SHELL}
export GCPOIDC_DRIVERS_TAR_FILE=/tmp/mongo-go-driver.tar.gz
# we need to statically link libc to avoid the situation where the VM has a different
# version of libc
go build -tags osusergo,netgo -ldflags '-w -extldflags "-static -lgcc -lc"' -o test ./cmd/testoidcauth/main.go
rm "$GCPOIDC_DRIVERS_TAR_FILE" || true
tar -cf $GCPOIDC_DRIVERS_TAR_FILE ./test
tar -uf $GCPOIDC_DRIVERS_TAR_FILE ./etc
rm "$GCPOIDC_DRIVERS_TAR_FILE".gz || true
gzip $GCPOIDC_DRIVERS_TAR_FILE
export GCPOIDC_DRIVERS_TAR_FILE=/tmp/mongo-go-driver.tar.gz
# Define the command to run on the gcp VM.
# Ensure that we source the environment file created for us, set up any other variables we need,
# and then run our test suite on the vm.
export GCPOIDC_TEST_CMD="PROJECT_DIRECTORY='.' OIDC_ENV=gcp OIDC=oidc ./etc/run-oidc-test.sh ./test"
bash $DRIVERS_TOOLS/.evergreen/auth_oidc/gcp/run-driver-test.sh

- name: "test-search-index"
commands:
- func: "bootstrap-mongo-orchestration"
Expand Down Expand Up @@ -2342,6 +2367,30 @@ task_groups:
tasks:
- oidc-auth-test-azure-latest

- name: testgcpoidc_task_group
setup_group:
- func: fetch-source
- func: prepare-resources
- func: fix-absolute-paths
- func: make-files-executable
- command: subprocess.exec
params:
binary: bash
env:
AZUREOIDC_VMNAME_PREFIX: "GO_DRIVER"
args:
- ${DRIVERS_TOOLS}/.evergreen/auth_oidc/gcp/setup.sh
teardown_task:
- command: subprocess.exec
params:
binary: bash
args:
- ${DRIVERS_TOOLS}/.evergreen/auth_oidc/gcp/teardown.sh
setup_group_can_fail_task: true
setup_group_timeout_secs: 1800
tasks:
- oidc-auth-test-gcp-latest

- name: test-aws-lambda-task-group
setup_group:
- func: fetch-source
Expand Down Expand Up @@ -2693,3 +2742,5 @@ buildvariants:
batchtime: 20160 # Use a batchtime of 14 days as suggested by the CSFLE test README
- name: testazureoidc_task_group
batchtime: 20160 # Use a batchtime of 14 days as suggested by the CSFLE test README
- name: testgcpoidc_task_group
batchtime: 20160 # Use a batchtime of 14 days as suggested by the CSFLE test README
22 changes: 22 additions & 0 deletions cmd/testoidcauth/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ func main() {
case "azure":
aux("machine_5_1_azureWithNoUsername", machine51azureWithNoUsername)
aux("machine_5_2_azureWithNoUsername", machine52azureWithBadUsername)
case "gcp":
aux("machine_6_1_gcpWithNoUsername", machine61gcpWithNoUsername)
default:
log.Fatal("Unknown OIDC_ENV: ", env)
}
Expand Down Expand Up @@ -736,3 +738,23 @@ func machine52azureWithBadUsername() error {
}
return nil
}

func machine61gcpWithNoUsername() error {
opts := options.Client().ApplyURI(uriSingle)
if opts == nil || opts.Auth == nil {
return fmt.Errorf("machine_6_1: failed parsing uri: %q", uriSingle)
}
client, err := mongo.Connect(context.Background(), opts)
if err != nil {
return fmt.Errorf("machine_6_1: failed connecting client: %v", err)
}
defer client.Disconnect(context.Background())

coll := client.Database("test").Collection("test")

_, err = coll.Find(context.Background(), bson.D{})
if err != nil {
return fmt.Errorf("machine_6_1: failed executing Find: %v", err)
}
return nil
}
42 changes: 37 additions & 5 deletions x/mongo/driver/auth/oidc.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"context"
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"strings"
Expand Down Expand Up @@ -174,12 +175,12 @@ func (oa *OIDCAuthenticator) providerCallback() (OIDCCallback, error) {
return nil, newAuthError(fmt.Sprintf("%q must be specified for Azure OIDC", resourceProp), nil)
}
return getAzureOIDCCallback(oa.userName, resource, oa.httpClient), nil
// TODO GODRIVER-2806: Automatic token acquisition for GCP Identity Provider
// This is here just to pass the linter, it will be fixed in one of the above tickets.
case gcpEnvironmentValue:
return func(ctx context.Context, args *OIDCArgs) (*OIDCCredential, error) {
return nil, fmt.Errorf("automatic token acquisition for %q not implemented yet", env)
}, fmt.Errorf("automatic token acquisition for %q not implemented yet", env)
resource, ok := oa.AuthMechanismProperties[resourceProp]
if !ok {
return nil, newAuthError(fmt.Sprintf("%q must be specified for GCP OIDC", resourceProp), nil)
}
return getGCPOIDCCallback(resource, oa.httpClient), nil
}

return nil, fmt.Errorf("%q %q not supported for MONGODB-OIDC", environmentProp, env)
Expand Down Expand Up @@ -228,6 +229,37 @@ func getAzureOIDCCallback(clientID string, resource string, httpClient *http.Cli
}
}

// getGCPOIDCCallback returns the callback for the GCP Identity Provider.
func getGCPOIDCCallback(resource string, httpClient *http.Client) OIDCCallback {
// return the callback parameterized by the clientID and resource, also passing in the user
// configured httpClient.
return func(ctx context.Context, args *OIDCArgs) (*OIDCCredential, error) {
resource = url.QueryEscape(resource)
uri := fmt.Sprintf("http://metadata/computeMetadata/v1/instance/service-accounts/default/identity?audience=%s", resource)
req, err := http.NewRequestWithContext(ctx, http.MethodGet, uri, nil)
if err != nil {
return nil, newAuthError("error creating http request to GCP Identity Provider", err)
}
req.Header.Add("Metadata-Flavor", "Google")
resp, err := httpClient.Do(req)
if err != nil {
return nil, newAuthError("error getting access token from GCP Identity Provider", err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, newAuthError(fmt.Sprintf("failed to get a valid response from GCP Identity Provider, http code: %d", resp.StatusCode), nil)
}
accessToken, err := io.ReadAll(resp.Body)
if err != nil {
return nil, newAuthError("failed parsing reading response from GCP Identity Provider", err)
}
return &OIDCCredential{
AccessToken: string(accessToken),
ExpiresAt: nil,
}, nil
}
}

func (oa *OIDCAuthenticator) getAccessToken(
ctx context.Context,
conn driver.Connection,
Expand Down
Loading