Skip to content

Commit c26ea7a

Browse files
CLOUDP-279933: documentation (#462)
Co-authored-by: lmkerbey-mdb <[email protected]>
1 parent fb904b5 commit c26ea7a

File tree

1 file changed

+162
-9
lines changed

1 file changed

+162
-9
lines changed

docs/doc_4_authentication.md

Lines changed: 162 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
1-
# Authenticate using the Atlas Go SDK
1+
# Authenticating with the Atlas Go SDK
22

3-
The `atlas-sdk-go` library uses Digest authentication.
3+
The `atlas-sdk-go` library utilizes Digest authentication as its default authentication method.
44
You can [create an API key](https://www.mongodb.com/docs/atlas/configure-api-access/#create-an-api-key-in-an-organization) through the Atlas UI or the Atlas CLI.
55

6-
To learn more about API authentication, see [Atlas Administration API Authentication](https://www.mongodb.com/docs/atlas/api/api-authentication).
6+
To learn more about API authentication, refer to [Atlas Administration API Authentication](https://www.mongodb.com/docs/atlas/api/api-authentication).
77

8-
### Use the Atlas Go SDK in Your Code
8+
## Using the Atlas Go SDK in Your Code with Digest Authentication
99

10-
Construct a new Atlas SDK client, then use the services on the client to
11-
access different parts of the Atlas Admin API. For example:
10+
To access different parts of the Atlas Admin API, construct a new Atlas SDK client and use its services. For example:
1211

1312
```go
1413
package main
@@ -17,8 +16,8 @@ import (
1716
"context"
1817
"fmt"
1918
"log"
20-
"os"
21-
19+
"os"
20+
2221
"go.mongodb.org/atlas-sdk/v20241023001/admin"
2322
)
2423

@@ -30,7 +29,7 @@ func main() {
3029

3130
sdk, err := admin.NewClient(admin.UseDigestAuth(apiKey, apiSecret))
3231
if err != nil {
33-
log.Fatalf("Error when instantiating new client: %v", err)
32+
log.Fatalf("Error instantiating new client: %v", err)
3433
}
3534
projects, response, err := sdk.ProjectsApi.ListProjects(ctx).Execute()
3635
if err != nil {
@@ -40,3 +39,157 @@ func main() {
4039
fmt.Printf("Projects: %v\n", projects)
4140
}
4241
```
42+
43+
## (Preview) Using the Atlas Go SDK with Service Account Authentication
44+
45+
Atlas SDK Go provides OAuth Authentication using Service Accounts (currently available as a [Preview](https://www.mongodb.com/resources/beta-programs) feature)
46+
A Service Account implements an OAuth [client_credentials](https://oauth.net/2/grant-types/client-credentials) grant.
47+
For more information about feature please refer to [Service Account Public documentation.](https://www.mongodb.com/docs/atlas/api/service-accounts-overview/)
48+
49+
## OAuth Authentication
50+
51+
### Authenticating with OAuth ClientID and ClientSecret
52+
53+
### Admin API Authentication using Service Accounts
54+
55+
Authenticating using Service Accounts
56+
57+
```go
58+
package main
59+
60+
import (
61+
"log"
62+
"os"
63+
64+
"go.mongodb.org/atlas-sdk/v20241023001/admin"
65+
)
66+
67+
func main() {
68+
clientID := os.Getenv("MONGODB_ATLAS_CLIENT_ID")
69+
clientSecret := os.Getenv("MONGODB_ATLAS_CLIENT_SECRET")
70+
71+
if clientID == "" || clientSecret == "" {
72+
log.Fatal("Missing CLIENT_ID or CLIENT_SECRET environment variables")
73+
}
74+
75+
// Using ClientID and ClientSecret. No cache supported (nil).
76+
sdk, err := admin.NewClient(admin.UseOAuthAuth(clientID, clientSecret, nil))
77+
78+
// Make API calls
79+
}
80+
```
81+
82+
> NOTE: This method of initialization provides **No Ability to Revoke API**: once a token is issued, it cannot be invalidated until it expires.
83+
84+
### Specifying a Token Cache
85+
86+
In this example, we will demonstrate how to use the OAuth Client Credentials flow with a custom token cache.
87+
The cache allows you to store OAuth tokens for reuse across application restarts, improving efficiency by reducing the number of token requests to the authorization server. This reduction in requests also minimizes the impact of OAuth Token Limits and Rate Limiting.
88+
89+
```go
90+
package main
91+
92+
import (
93+
"context"
94+
"encoding/json"
95+
"log"
96+
"os"
97+
"sync"
98+
99+
"go.mongodb.org/atlas-sdk/v20241023001/auth/credentials"
100+
"go.mongodb.org/atlas-sdk/v20241023001/admin"
101+
)
102+
103+
type MyTokenCache struct {
104+
fileContent []byte
105+
mu sync.Mutex
106+
}
107+
108+
func (s *MyTokenCache) RetrieveToken(_ context.Context) (string, error) {
109+
s.mu.Lock()
110+
defer s.mu.Unlock()
111+
112+
var tkn string
113+
err := json.Unmarshal(s.fileContent, &tkn)
114+
if err != nil {
115+
return "", err
116+
}
117+
118+
return tkn, nil
119+
}
120+
121+
func (s *MyTokenCache) SaveToken(_ context.Context, tkn string) error {
122+
s.mu.Lock()
123+
defer s.mu.Unlock()
124+
125+
fileData, err := json.Marshal(tkn)
126+
if err != nil {
127+
return err
128+
}
129+
s.fileContent = fileData
130+
return nil
131+
}
132+
133+
func main() {
134+
clientID := os.Getenv("MONGODB_ATLAS_CLIENT_ID")
135+
clientSecret := os.Getenv("MONGODB_ATLAS_CLIENT_SECRET")
136+
137+
if clientID == "" || clientSecret == "" {
138+
log.Fatal("Missing CLIENT_ID or CLIENT_SECRET environment variables")
139+
}
140+
141+
fileTokenCache := MyTokenCache{}
142+
// Using ClientID and ClientSecret. No cache supported (nil).
143+
httpClient, err := admin.NewClient(admin.UseOAuthAuth(clientID, clientSecret, fileTokenCache))
144+
sdk, err := admin.NewClient(admin.UseHTTPClient(httpClient))
145+
146+
// Make requests to the API
147+
// ...
148+
// Revoke Token
149+
_ = tokenSource.RevokeToken()
150+
}
151+
```
152+
153+
## Advanced Use Cases
154+
155+
### Revocation
156+
157+
Revocation invalidates an OAuth token before its expiration date. This effectively "logs out" the current OAuth client and allows you to configure a new client.
158+
159+
```go
160+
// Sounding code omitted for brevity
161+
err := tokenSource.RevokeToken()
162+
if err != nil {
163+
log.Fatalf("Error: %v", err)
164+
}
165+
```
166+
167+
### Creating a Custom Transport
168+
169+
You can create a custom transport to inject the OAuth token into HTTP requests.
170+
The `OAuthCustomHTTPTransport` provides an `UnderlyingTransport` field that specifies the transport to use for requests.
171+
172+
```go
173+
tokenSource := credentials.NewTokenSourceWithOptions(credentials.AtlasTokenSourceOptions{
174+
ClientID: clientID,
175+
ClientSecret: clientSecret,
176+
})
177+
178+
transport := OAuthCustomHTTPTransport{
179+
UnderlyingTransport: <your_transport>,
180+
TokenSource: tokenSource,
181+
}
182+
// Use transport with your own HTTP client or create a new one.
183+
```
184+
185+
### Overriding the User Agent
186+
187+
You can override the default user agent by specifying an agent of your choice in the `AtlasTokenSourceOptions`.
188+
189+
```go
190+
tokenSource := credentials.NewTokenSourceWithOptions(credentials.AtlasTokenSourceOptions{
191+
ClientID: clientID,
192+
ClientSecret: clientSecret,
193+
UserAgent: "CustomUserAgent/1.0",
194+
})
195+
```

0 commit comments

Comments
 (0)