Skip to content

Commit 90a6c8b

Browse files
blvacveticmjeroenvervaekeWaybo26fmenezes
authored
CLOUDP-304203: Add support to Service Accounts (#4130)
Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: Melanija Cvetic <[email protected]> Co-authored-by: Jeroen Vervaeke <[email protected]> Co-authored-by: Wesley Nabo <[email protected]> Co-authored-by: Filipe Constantinov Menezes <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: apix-bot[bot] <168195273+apix-bot[bot]@users.noreply.github.com> Co-authored-by: Jeroen Vervaeke <[email protected]>
1 parent b5c3ba9 commit 90a6c8b

File tree

443 files changed

+6041
-1769
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

443 files changed

+6041
-1769
lines changed

.golangci.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,8 @@ linters:
145145
alias: storeTransport
146146
- pkg: github.com/mongodb/mongodb-atlas-cli/atlascli/tools/shared/api
147147
alias: shared_api
148+
- pkg: github.com/mongodb/atlas-cli-core/mocks
149+
alias: coreMocks
148150
no-extra-aliases: true
149151
misspell:
150152
locale: US

SECURITY.md

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,47 @@
22

33
## Reporting a Vulnerability
44

5-
Any security concerns or vulnerabilities discovered in one of MongoDBs products or hosted services
5+
Any security concerns or vulnerabilities discovered in one of MongoDB's products or hosted services
66
can be responsibly disclosed by utilizing one of the methods described in our [create a vulnerability report](https://docs.mongodb.com/manual/tutorial/create-a-vulnerability-report/) docs page.
77

88
While we greatly appreciate community reports regarding security issues, at this time MongoDB does not provide compensation for vulnerability reports.
9+
10+
## Credential Storage
11+
12+
The MongoDB Atlas CLI uses a hybrid approach to store sensitive credentials, prioritizing security while maintaining compatibility across different environments and systems.
13+
14+
### Secure Storage (Preferred)
15+
16+
When available, the CLI uses your operating system's native keyring services to securely store sensitive credentials. This provides the highest level of security by leveraging OS-level encryption and access controls.
17+
18+
**Credentials stored securely include:**
19+
- API Keys (public and private)
20+
- Access Tokens
21+
- Refresh Tokens
22+
- Client ID and Client Secret
23+
24+
**Supported platforms:**
25+
- **macOS**: Uses Keychain Services for secure credential storage
26+
- **Windows**: Integrates with Windows Credential Manager
27+
- **Linux**: Works with desktop [Secret Service](https://specifications.freedesktop.org/secret-service-spec/latest/) dbus interface
28+
29+
### Insecure Storage (Fallback)
30+
31+
If the operating system's keyring services are unavailable, the CLI automatically falls back to storing credentials in a local configuration file (`config.toml`). This ensures the CLI remains functional even in restricted environments.
32+
33+
**Important security considerations for fallback storage:**
34+
- Credentials are stored in plain text in the configuration file
35+
36+
### Checking Your Storage Method
37+
38+
You can verify whether your CLI is using secure storage by running any `atlas` command. You'll see the message `Warning: Secure storage is not available, falling back to insecure storage`, when secure storage is not available.
39+
40+
### Technical Implementation
41+
42+
The CLI uses the [go-keyring](https://github.com/zalando/go-keyring) library to interface with OS keyring services. Each profile's credentials are stored under a service name prefixed with `atlascli_` (e.g., `atlascli_default` for the default profile).
43+
44+
For detailed information about how your operating system manages keyring encryption and security:
45+
46+
- **macOS Keychain**: [Apple Keychain Services Documentation](https://developer.apple.com/documentation/security/keychain_services)
47+
- **Windows Credential Manager**: [Windows Credential Manager Documentation](https://docs.microsoft.com/en-us/windows/security/identity-protection/credential-guard/)
48+
- **Linux GNOME Keyring**: [GNOME Keyring Documentation](https://wiki.gnome.org/Projects/GnomeKeyring)

build/ci/evergreen.yml

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -685,6 +685,18 @@ tasks:
685685
- func: "e2e test"
686686
vars:
687687
E2E_TEST_PACKAGES: ./test/e2e/atlas/serverless/instance/...
688+
- name: atlas_service_account_e2e
689+
tags: ["e2e","generic","atlas"]
690+
must_have_test_results: true
691+
depends_on:
692+
- name: compile
693+
variant: "code_health"
694+
patch_optional: true
695+
commands:
696+
- func: "install gotestsum"
697+
- func: "e2e test"
698+
vars:
699+
E2E_TEST_PACKAGES: ./test/e2e/atlas/serviceAccount/...
688700
- name: atlas_gov_clusters_flags_e2e
689701
tags: ["e2e","clusters","atlasgov","foliage_check_task_only"]
690702
must_have_test_results: true
@@ -1365,6 +1377,25 @@ tasks:
13651377
-e SNYK_CFG_ORG=${SNYK_ORG} \
13661378
-v ${workdir}/src/github.com/mongodb/mongodb-atlas-cli:/app \
13671379
snyk/snyk:golang snyk monitor
1380+
#
1381+
- name: atlas_config_migration_e2e
1382+
tags: ["e2e","config-migration"]
1383+
must_have_test_results: true
1384+
depends_on:
1385+
- name: compile
1386+
variant: "code_health"
1387+
patch_optional: true
1388+
commands:
1389+
- func: "install gotestsum"
1390+
- func: "e2e test"
1391+
vars:
1392+
MONGODB_ATLAS_ORG_ID: ${atlas_org_id}
1393+
MONGODB_ATLAS_PROJECT_ID: ${atlas_project_id}
1394+
MONGODB_ATLAS_PRIVATE_API_KEY: ${atlas_private_api_key}
1395+
MONGODB_ATLAS_PUBLIC_API_KEY: ${atlas_public_api_key}
1396+
MONGODB_ATLAS_OPS_MANAGER_URL: ${mcli_ops_manager_url}
1397+
MONGODB_ATLAS_SERVICE: cloud
1398+
E2E_TEST_PACKAGES: ./test/e2e/config/migration/...
13681399
task_groups:
13691400
- name: atlas_deployments_windows_group
13701401
setup_task:
@@ -1683,6 +1714,18 @@ buildvariants:
16831714
- ubuntu2204-small
16841715
tasks:
16851716
- name: ".snyk"
1717+
- name: e2e_config_migration_macos_14
1718+
display_name: "E2E Config Migration Tests"
1719+
allowed_requesters: ["patch", "ad_hoc", "github_pr"]
1720+
tags:
1721+
- config-migration
1722+
- foliage_health
1723+
run_on:
1724+
- macos-14-arm64-docker
1725+
expansions:
1726+
<<: *go_linux_version
1727+
tasks:
1728+
- name: ".e2e .config-migration"
16861729
patch_aliases:
16871730
- alias: "localdev"
16881731
variant_tags: ["localdev cron"]
@@ -1707,4 +1750,4 @@ git_tag_aliases:
17071750
task: ".*"
17081751
github_checks_aliases:
17091752
- variant: ".*"
1710-
task: ".*"
1753+
task: ".*"

build/ci/library_owners.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
"github.com/mholt/archives": "apix-2",
2727
"github.com/mongodb-forks/digest": "apix-2",
2828
"github.com/mongodb-labs/cobra2snooty": "apix-2",
29+
"github.com/mongodb/atlas-cli-core": "apix-2",
2930
"github.com/Netflix/go-expect": "apix-2",
3031
"github.com/PaesslerAG/jsonpath": "apix-2",
3132
"github.com/pelletier/go-toml": "apix-2",
@@ -40,6 +41,7 @@
4041
"github.com/stretchr/testify": "apix-2",
4142
"github.com/tangzero/inflector": "apix-2",
4243
"github.com/yuin/goldmark": "apix-2",
44+
"github.com/zalando/go-keyring": "apix-2",
4345
"go.mongodb.org/atlas-sdk/v20240530005": "apix-2",
4446
"go.mongodb.org/atlas-sdk/v20250312006": "apix-2",
4547
"go.mongodb.org/atlas": "apix-2",
@@ -50,6 +52,7 @@
5052
"go.uber.org/mock": "apix-2",
5153
"golang.org/x/mod": "apix-2",
5254
"golang.org/x/net": "apix-2",
55+
"golang.org/x/oauth2": "apix-2",
5356
"golang.org/x/sys": "apix-2",
5457
"golang.org/x/tools": "apix-2",
5558
"google.golang.org/api": "apix-2",

build/package/purls.txt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
pkg:golang/al.essio.dev/pkg/[email protected]
12
pkg:golang/cloud.google.com/go/auth/[email protected]
23
pkg:golang/cloud.google.com/go/[email protected]
34
pkg:golang/cloud.google.com/go/compute/[email protected]
@@ -38,16 +39,18 @@ pkg:golang/github.com/briandowns/[email protected]
3839
pkg:golang/github.com/cli/go-gh/[email protected]
3940
pkg:golang/github.com/cli/[email protected]
4041
pkg:golang/github.com/cloudflare/[email protected]
42+
pkg:golang/github.com/danieljoos/[email protected]
4143
pkg:golang/github.com/denisbrodbeck/[email protected]
4244
pkg:golang/github.com/dsnet/[email protected]
4345
pkg:golang/github.com/ebitengine/[email protected]
4446
pkg:golang/github.com/fatih/[email protected]
4547
pkg:golang/github.com/felixge/[email protected]
46-
pkg:golang/github.com/fsnotify/fsnotify@v1.8.0
48+
pkg:golang/github.com/fsnotify/fsnotify@v1.9.0
4749
pkg:golang/github.com/go-logr/[email protected]
4850
pkg:golang/github.com/go-logr/[email protected]
4951
pkg:golang/github.com/go-ole/[email protected]
5052
pkg:golang/github.com/go-viper/mapstructure/[email protected]
53+
pkg:golang/github.com/godbus/dbus/[email protected]
5154
pkg:golang/github.com/golang-jwt/jwt/[email protected]
5255
pkg:golang/github.com/golang/[email protected]
5356
pkg:golang/github.com/google/go-github/[email protected]
@@ -72,6 +75,7 @@ pkg:golang/github.com/mholt/[email protected]
7275
pkg:golang/github.com/mikelolasagasti/[email protected]
7376
pkg:golang/github.com/minio/[email protected]
7477
pkg:golang/github.com/mongodb-forks/[email protected]
78+
pkg:golang/github.com/mongodb/[email protected]
7579
pkg:golang/github.com/montanaflynn/[email protected]
7680
pkg:golang/github.com/nwaples/rardecode/[email protected]
7781
pkg:golang/github.com/pelletier/go-toml/[email protected]
@@ -97,6 +101,7 @@ pkg:golang/github.com/xdg-go/[email protected]
97101
pkg:golang/github.com/xdg-go/[email protected]
98102
pkg:golang/github.com/youmark/[email protected]
99103
pkg:golang/github.com/yusufpapurcu/[email protected]
104+
pkg:golang/github.com/zalando/[email protected]
100105
pkg:golang/go.mongodb.org/atlas-sdk/[email protected]
101106
pkg:golang/go.mongodb.org/atlas-sdk/[email protected]
102107
pkg:golang/go.mongodb.org/[email protected]

cmd/atlas/atlas.go

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,27 +15,31 @@
1515
package main
1616

1717
import (
18+
"context"
1819
"fmt"
1920
"log"
2021
"os"
2122
"strings"
2223

2324
"github.com/AlecAivazis/survey/v2/core"
25+
"github.com/mongodb/atlas-cli-core/config"
26+
"github.com/mongodb/mongodb-atlas-cli/atlascli/internal/cli/commonerrors"
2427
"github.com/mongodb/mongodb-atlas-cli/atlascli/internal/cli/root"
25-
"github.com/mongodb/mongodb-atlas-cli/atlascli/internal/config"
28+
"github.com/mongodb/mongodb-atlas-cli/atlascli/internal/config/migrations"
2629
"github.com/mongodb/mongodb-atlas-cli/atlascli/internal/telemetry"
2730
"github.com/spf13/cobra"
2831
)
2932

3033
// Execute adds all child commands to the root command and sets flags appropriately.
3134
// This is called by main.main(). It only needs to happen once to the rootCmd.
32-
func execute(rootCmd *cobra.Command) {
33-
ctx := telemetry.NewContext()
35+
func execute(ctx context.Context, rootCmd *cobra.Command) {
3436
// append here to avoid a recursive link on generated docs
3537
rootCmd.Long += `
3638
3739
To learn more, see our documentation: https://www.mongodb.com/docs/atlas/cli/stable/connect-atlas-cli/`
3840
if cmd, err := rootCmd.ExecuteContextC(ctx); err != nil {
41+
err := commonerrors.Check(err)
42+
rootCmd.PrintErrln(rootCmd.ErrPrefix(), err)
3943
if !telemetry.StartedTrackingCommand() {
4044
telemetry.StartTrackingCommand(cmd, os.Args[1:])
4145
}
@@ -48,12 +52,27 @@ To learn more, see our documentation: https://www.mongodb.com/docs/atlas/cli/sta
4852
}
4953

5054
// loadConfig reads in config file and ENV variables if set.
51-
func loadConfig() error {
52-
if err := config.LoadAtlasCLIConfig(); err != nil {
53-
return fmt.Errorf("error loading config: %w. Please run `atlas config init` to reconfigure your profile", err)
55+
func loadConfig() (*config.Profile, error) {
56+
// Migrate config to the latest version.
57+
migrator := migrations.NewDefaultMigrator()
58+
if err := migrator.Migrate(); err != nil {
59+
return nil, fmt.Errorf("error migrating config: %w", err)
60+
}
61+
62+
configStore, initErr := config.NewDefaultStore()
63+
64+
if initErr != nil {
65+
return nil, fmt.Errorf("error loading config: %w. Please run `atlas auth login` to reconfigure your profile", initErr)
66+
}
67+
68+
if !configStore.IsSecure() {
69+
fmt.Fprintf(os.Stderr, "Warning: Secure storage is not available, falling back to insecure storage\n")
5470
}
5571

56-
return nil
72+
profile := config.NewProfile(config.DefaultProfile, configStore)
73+
config.SetProfile(profile)
74+
75+
return profile, nil
5776
}
5877

5978
func trackInitError(e error, rootCmd *cobra.Command) {
@@ -82,9 +101,18 @@ func main() {
82101
core.DisableColor = true
83102
}
84103

104+
// Load config
105+
profile, loadProfileErr := loadConfig()
106+
85107
rootCmd := root.Builder()
86108
initTrack(rootCmd)
87-
trackInitError(loadConfig(), rootCmd)
109+
trackInitError(loadProfileErr, rootCmd)
110+
111+
// Initialize context, attach
112+
// - telemetry
113+
// - profile
114+
ctx := telemetry.NewContext()
115+
config.WithProfile(ctx, profile)
88116

89-
execute(rootCmd)
117+
execute(ctx, rootCmd)
90118
}

docs/command/atlas-auth-login.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ atlas auth login
1414

1515
Authenticate with MongoDB Atlas.
1616

17+
This command allows you to authenticate with MongoDB Atlas using User Account, Service Account, or API Key authentication methods.
18+
1719
Syntax
1820
------
1921

@@ -46,7 +48,7 @@ Options
4648
* - --noBrowser
4749
-
4850
- false
49-
- Don't try to open a browser session.
51+
- Don't automatically open a browser session.
5052

5153
Inherited Options
5254
-----------------

0 commit comments

Comments
 (0)