Skip to content
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

feat: use workload identity federation to gain access to google #150

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 0 additions & 1 deletion .goreleaser.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,3 @@ archives:
format_overrides:
- goos: windows
format: zip

30 changes: 27 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,32 @@ as locally running the ssosync tool.

### Google

First, you have to setup your API. In the project you want to use go to the [Console](https://console.developers.google.com/apis) and select *API & Services* > *Enable APIs and Services*. Search for *Admin SDK* and *Enable* the API.
First, you have to setup your API. In the project you want to use go to the [Console](https://console.developers.google.com/apis) and select
*API & Services* > *Enable APIs and Services*. Search for *Admin SDK* and *Enable* the API.

You have to perform this [tutorial](https://developers.google.com/admin-sdk/directory/v1/guides/delegation) to create a service account that you use to sync your users. Save the `JSON file` you create during the process and rename it to `credentials.json`.
You have to perform this [tutorial](https://developers.google.com/admin-sdk/directory/v1/guides/delegation) to create a
service account that you use to sync your users. This is the service account that is used to impersonate a user
(via `--google-admin`). You have two possibilities to use this service account. Create a service account key credential,
as describe in the tutorial above. Or use
[Workload Identity Federation](https://cloud.google.com/iam/docs/workload-identity-federation).

#### Service account key credential

Save the `JSON file` you create during the process described in the tutorial above and rename it to `credentials.json`.
Please, keep this file safe, or store it in the AWS Secrets Manager.

#### Workload Identity Federation

Set up Workload Identity Federation for AWS as described
[here](https://cloud.google.com/iam/docs/workload-identity-federation-with-other-clouds) and save the `JSON file`, and
rename it to `credentials.json`. Provide the email address of service account used to impersonate a user using
`--google-service-account-email`.
Note that the `JSON file` created using this approach **does not** contain any sensitive data.

> You can also use the `--google-credentials` parameter to explicitly specify the file containing the credentials.
> Setting this parameter to an empty string will use
> [Application Default Credentials](https://cloud.google.com/docs/authentication/application-default-credentials).

> you can also use the `--google-credentials` parameter to explicitly specify the file with the service credentials. Please, keep this file safe, or store it in the AWS Secrets Manager

In the domain-wide delegation for the Admin API, you have to specify the following scopes for the user.

Expand All @@ -89,6 +110,9 @@ In the Search box type `Admin` and select the `Admin SDK` option. Click the `Ena

You will have to specify the email address of an admin via `--google-admin` to assume this users role in the Directory.

> When running this tool as AWS Lambda, the parameter `--google-credentials` is expected to contain the content of the
> `JSON file`.

### AWS

Go to the AWS Single Sign-On console in the region you have set up AWS SSO and select
Expand Down
1 change: 1 addition & 0 deletions SAR.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ There are general configuration parameters to the application stack.

* `GoogleCredentials` contains the content of the `credentials.json` file
* `GoogleAdminEmail` contains the email address of an admin
* `GoogleSAEmail` contains the email address of a Google service account used to impersonate the admin user

The secrets are stored in the [AWS Secrets Manager](https://aws.amazon.com/secrets-manager/).

Expand Down
16 changes: 12 additions & 4 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,14 @@ import (
"fmt"
"os"

"github.com/awslabs/ssosync/internal"
"github.com/awslabs/ssosync/internal/config"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-lambda-go/events"
"github.com/aws/aws-sdk-go/service/codepipeline"
"github.com/aws/aws-lambda-go/lambda"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/codepipeline"
"github.com/aws/aws-sdk-go/service/secretsmanager"
"github.com/awslabs/ssosync/internal"
"github.com/awslabs/ssosync/internal/config"
"github.com/pkg/errors"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
Expand Down Expand Up @@ -157,6 +157,7 @@ func initConfig() {

appEnvVars := []string{
"google_admin",
"google_sa_email",
"google_credentials",
"scim_access_token",
"scim_endpoint",
Expand Down Expand Up @@ -201,6 +202,12 @@ func configLambda() {
}
cfg.GoogleAdmin = unwrap

unwrap, err = secrets.GoogleSAEmail()
if err != nil {
log.Fatalf(errors.Wrap(err, "cannot read config").Error())
}
cfg.GoogleSAEmail = unwrap

unwrap, err = secrets.GoogleCredentials()
if err != nil {
log.Fatalf(errors.Wrap(err, "cannot read config").Error())
Expand Down Expand Up @@ -241,6 +248,7 @@ func addFlags(cmd *cobra.Command, cfg *config.Config) {
rootCmd.Flags().StringVarP(&cfg.SCIMEndpoint, "endpoint", "e", "", "AWS SSO SCIM API Endpoint")
rootCmd.Flags().StringVarP(&cfg.GoogleCredentials, "google-credentials", "c", config.DefaultGoogleCredentials, "path to Google Workspace credentials file")
rootCmd.Flags().StringVarP(&cfg.GoogleAdmin, "google-admin", "u", "", "Google Workspace admin user email")
rootCmd.Flags().StringVarP(&cfg.GoogleSAEmail, "google-service-account-email", "W", "", "Google Workload Identity Federation SA email. If set, google-credentials must be associated with a Workload Identity Federation json file")
rootCmd.Flags().StringSliceVar(&cfg.IgnoreUsers, "ignore-users", []string{}, "ignores these Google Workspace users")
rootCmd.Flags().StringSliceVar(&cfg.IgnoreGroups, "ignore-groups", []string{}, "ignores these Google Workspace groups")
rootCmd.Flags().StringSliceVar(&cfg.IncludeGroups, "include-groups", []string{}, "include only these Google Workspace groups, NOTE: only works when --sync-method 'users_groups'")
Expand Down
47 changes: 29 additions & 18 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,36 @@ module github.com/awslabs/ssosync
go 1.16

require (
github.com/BurntSushi/toml v1.0.0
github.com/aws/aws-lambda-go v1.23.0
github.com/aws/aws-sdk-go v1.44.102
github.com/fsnotify/fsnotify v1.4.9 // indirect
github.com/golang/mock v1.5.0
github.com/BurntSushi/toml v1.3.2
github.com/aws/aws-lambda-go v1.41.0
github.com/aws/aws-sdk-go v1.44.319
github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c // indirect
github.com/coreos/bbolt v1.3.2 // indirect
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e // indirect
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f // indirect
github.com/dgrijalva/jwt-go v3.2.0+incompatible // indirect
github.com/golang/mock v1.6.0
github.com/gorilla/websocket v1.4.2 // indirect
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-retryablehttp v0.7.0
github.com/magiconair/properties v1.8.5 // indirect
github.com/mitchellh/mapstructure v1.4.1 // indirect
github.com/pelletier/go-toml v1.9.0 // indirect
github.com/hashicorp/go-retryablehttp v0.7.4
github.com/jonboulle/clockwork v0.1.0 // indirect
github.com/pelletier/go-toml v1.9.5 // indirect
github.com/pelletier/go-toml/v2 v2.0.9 // indirect
github.com/pkg/errors v0.9.1
github.com/sirupsen/logrus v1.8.1
github.com/spf13/afero v1.6.0 // indirect
github.com/spf13/cast v1.3.1 // indirect
github.com/spf13/cobra v1.1.3
github.com/prometheus/tsdb v0.7.1 // indirect
github.com/sirupsen/logrus v1.9.3
github.com/smartystreets/goconvey v1.6.4 // indirect
github.com/soheilhy/cmux v0.1.4 // indirect
github.com/spf13/cobra v1.7.0
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/spf13/viper v1.7.1
github.com/stretchr/testify v1.7.0
golang.org/x/oauth2 v0.0.0-20210427180440-81ed05c6b58c
google.golang.org/api v0.46.0
gopkg.in/ini.v1 v1.62.0 // indirect
github.com/spf13/viper v1.16.0
github.com/stretchr/testify v1.8.4
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5 // indirect
github.com/urfave/cli/v2 v2.2.0 // indirect
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 // indirect
go.etcd.io/bbolt v1.3.2 // indirect
golang.org/x/oauth2 v0.11.0
google.golang.org/api v0.136.0
gopkg.in/resty.v1 v1.12.0 // indirect
)
Loading