Skip to content

Commit

Permalink
Add various cleanliness changes (#114)
Browse files Browse the repository at this point in the history
* Use oauth2 package for the token exchange call

This should also fix a bug where non-HTTP 200 responses are not caught
and result in a cryptic error later in the exchange process

* Use OAuth2 package more heavily to simplify code

* Pass client through context. This would normally be frowned upon but
  we know we will only be using OAuth2's APIs to interact with Okta
  anyway.
* Implement oauth2.TokenSource on TokenSet, which removes the need to
  manually construct *oauth2.Token.

* Parse the ID token in LoginCommand, not in the Config

The config shouldn't "know" anything about the minutae of the token it
is receiving.

* Move socket creation into LoginCommand

Takes the HandlePendingSession function much simpler

* Move port handling out of the oauth2 file

* Use ClientContext() instead of the context key directly

* Use slices.Contains() instead of our own custom function

* Refactor Get to have a struct, like Login

* Use a writer pattern for exporting environment variables

* Move things around to reduce symbols in main package

* Remove unused package go-rootcerts

This was necessary due a bug in Go
(golang/go#14514) that was resolved in Go 1.8.

* Move oauth2 things of the command package

* Remove partial Tencent Cloud support

This will be reimplemented at some point in the future, but this has not
been working since 85f224a and attempting to use it results in a
run-time panic.

* Use OIDC library for fetching UserInfo

The UserInfo endpoint for Okta is standards-compliant, so we should use
a standards-compliant library to access it

* Use newer versions of Go & aws-lambda-go

* Use the v2 AWS SDK

* Use official Hashicorp SDK for Vault

* Do not use AWS auth for Vault

Instead of using AWS authentication for Vault, users should be
instructed to use the Hashicorp Vault extension for AWS Lambda;
KeyConjurer's Lambda functions are not made aware of any authentication
details.

https://developer.hashicorp.com/vault/docs/platform/aws/lambda-extension

* Rename the environment variables

VAULT_SECRET_PATH conflicts with the Lambda extension.

* Correct key-value

* Put binaries in bin/

* Remove unused packages

* Disable CGO

* Fix secret decoding

* Remove the Lambdaify handler to simplify code

* Convert Switch command to be struct-based

* Update LoginCommand to match SwitchCommand

* Remove flags and command from GetCommand

* Hide OIDC flags

* Update Windows and WSL usage instructions

Co-authored-by: dpantry <[email protected]>
Co-authored-by: ext-jmendes <[email protected]>

---------

Co-authored-by: ext-jmendes <[email protected]>
  • Loading branch information
punmechanic and ext-jmendes authored Nov 21, 2024
1 parent 2801c91 commit 5ff3e2f
Show file tree
Hide file tree
Showing 52 changed files with 1,489 additions and 2,020 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -249,3 +249,4 @@ cli/keyconjurer-darwin*
cli/keyconjurer-linux*
cli/keyconjurer-windows.exe
vendor
bin/
46 changes: 24 additions & 22 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,19 @@
RELEASE ?= dev
VERSION ?= $(shell git rev-parse --short HEAD)
# This runs on Linux machines. Mac users should override TIMESTAMP.
TIMESTAMP ?= $(shell date --iso-8601=minutes)
TIMESTAMP ?= $(-shell date --iso-8601=minutes)

## Standard targets for all Makefiles in our team

all: build

clean:
rm -rf cli/keyconjurer*
rm -rf bin/keyconjurer*
rm -r frontend/dist

test: frontend_test go_test

CLI_TARGETS = cli/keyconjurer-darwin cli/keyconjurer-darwin-amd64 cli/keyconjurer-darwin-arm64 cli/keyconjurer-linux cli/keyconjurer-linux-amd64 cli/keyconjurer-linux-arm64 cli/keyconjurer-windows.exe
CLI_TARGETS = bin/keyconjurer-darwin bin/keyconjurer-darwin-amd64 bin/keyconjurer-darwin-arm64 bin/keyconjurer-linux bin/keyconjurer-linux-amd64 bin/keyconjurer-linux-arm64 bin/keyconjurer-windows.exe
build: api_build frontend/dist/index.html $(CLI_TARGETS)

go_test:
Expand All @@ -32,46 +32,48 @@ frontend/dist/index.html: frontend/node_modules
VITE_APP_VERSION='$(shell git rev-parse --short HEAD)-$(RELEASE)' cd frontend && npm run-script build

### CLI Build Targets
cli/keyconjurer-linux-arm64 cli/keyconjurer-linux:
GOOS=linux GOARCH=amd64 BUILD_TARGET=keyconjurer-linux $(MAKE) cli/keyconjurer
GOOS=linux GOARCH=arm64 BUILD_TARGET=keyconjurer-linux-arm64 $(MAKE) cli/keyconjurer
bin/keyconjurer-linux-arm64 bin/keyconjurer-linux:
GOOS=linux GOARCH=amd64 BUILD_TARGET=keyconjurer-linux $(MAKE) bin/keyconjurer
GOOS=linux GOARCH=arm64 BUILD_TARGET=keyconjurer-linux-arm64 $(MAKE) bin/keyconjurer

cli/keyconjurer-linux-amd64: cli/keyconjurer-linux
cp cli/keyconjurer-linux cli/keyconjurer-linux-amd64
bin/keyconjurer-linux-amd64: bin/keyconjurer-linux
cp bin/keyconjurer-linux bin/keyconjurer-linux-amd64

cli/keyconjurer-darwin-arm64 cli/keyconjurer-darwin:
GOOS=darwin GOARCH=amd64 BUILD_TARGET=keyconjurer-darwin $(MAKE) cli/keyconjurer
GOOS=darwin GOARCH=arm64 BUILD_TARGET=keyconjurer-darwin-arm64 $(MAKE) cli/keyconjurer
bin/keyconjurer-darwin-arm64 bin/keyconjurer-darwin:
GOOS=darwin GOARCH=amd64 BUILD_TARGET=keyconjurer-darwin $(MAKE) bin/keyconjurer
GOOS=darwin GOARCH=arm64 BUILD_TARGET=keyconjurer-darwin-arm64 $(MAKE) bin/keyconjurer

cli/keyconjurer-darwin-amd64: cli/keyconjurer-darwin
cp cli/keyconjurer-darwin cli/keyconjurer-darwin-amd64
bin/keyconjurer-darwin-amd64: bin/keyconjurer-darwin
cp bin/keyconjurer-darwin bin/keyconjurer-darwin-amd64

cli/keyconjurer-windows.exe:
GOOS=windows GOARCH=amd64 BUILD_TARGET=keyconjurer-windows.exe $(MAKE) cli/keyconjurer
bin/keyconjurer-windows.exe:
GOOS=windows GOARCH=amd64 BUILD_TARGET=keyconjurer-windows.exe $(MAKE) bin/keyconjurer

cli/keyconjurer:
bin/keyconjurer: bin/
@test $${CLIENT_ID?is not set}
@test $${OIDC_DOMAIN?is not set}
@test $${SERVER_ADDRESS?is not set}
cd cli && \
go build \
@go build \
-ldflags "\
-s -w \
-X main.Version=$(shell git rev-parse --short HEAD)-$(RELEASE) \
-X main.ClientID=$(CLIENT_ID) \
-X main.OIDCDomain=$(OIDC_DOMAIN) \
-X main.BuildTimestamp='$(TIMESTAMP)' \
-X main.ServerAddress=$(SERVER_ADDRESS)" \
-o $(BUILD_TARGET)
-o bin/$(BUILD_TARGET)

bin/:
mkdir -p bin/

## API Build Targets
api_build: build/list_applications.zip

build/list_applications.zip:
mkdir -p build/cli
mkdir -p build
# A temporary destination is used because we don't want multiple targets run at the same time to conflict - they all have to be named 'bootstrap'
TMP_DST=$$(mktemp -d) ;\
GOOS=linux GOARCH=amd64 go build \
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build \
-tags lambda.norpc \
-o $$TMP_DST/bootstrap lambda/$(subst .zip,,$(notdir $@))/main.go && \
(cd $$TMP_DST && zip - bootstrap) > $@
Expand All @@ -83,7 +85,7 @@ upload: api_upload cli_upload frontend_upload
cli_upload: $(CLI_TARGETS)
@test $${S3_FRONTEND_BUCKET_NAME?is not set}
@test $${RELEASE?is not set}
cd cli/ && \
cd bin/ && \
aws s3 cp . s3://$(S3_FRONTEND_BUCKET_NAME)-$(RELEASE) --exclude "*" --include "keyconjurer*" --recursive

frontend_upload: frontend/dist/index.html
Expand Down
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ KeyConjurer is made of three parts:
- [cli](./cli/) - The CLI interface.
- [frontend](./frontend/) - A static webpage which informs users on how to download and use KeyConjurer.

KeyConjurer is designed to work with Okta as an IdP, supports AWS and Tencent Cloud applications, and is inspired in part by [okta-aws-cli](https://github.com/okta/okta-aws-cli). The main difference from okta-aws-cli is that KeyConjurer does not require all users to have access to the Okta administration API - Instead, we use a Lambda function to access the protected resources required.
KeyConjurer is designed to work with Okta as an IdP, supports AWS applications, and is inspired in part by [okta-aws-cli](https://github.com/okta/okta-aws-cli). The main difference from okta-aws-cli is that KeyConjurer does not require all users to have access to the Okta administration API - Instead, we use a Lambda function to access the protected resources required.

We use KeyConjurer a lot at Riot, but we can't guarantee any external support for this project. It's use at your own risk. If you encounter a bug or have a feature request, please feel free to raise a pull request or an issue against this repository. You're also welcome to fork the code and modify it as you see fit.

Expand Down Expand Up @@ -48,7 +48,7 @@ In order to use KeyConjurer, an Okta administrator must configure their tenant a
* Authorization Types: Hybrid Flow, Authorization Code, Token Exchange
* Redirection URI: http://localhost:57468
* We recommend you enable Federated Mode on this native application so that users don't need to be explicitly assigned to it.
* All AWS and tencent applications must have their Allowed Web SSO Client set to the _Client ID_ of the native OIDC application that was created. This can be configured by going to the Sign On tab for each individual Okta application or managing the application configuration in an IAC provider, like Terraform.
* All AWS applications must have their Allowed Web SSO Client set to the _Client ID_ of the native OIDC application that was created. This can be configured by going to the Sign On tab for each individual Okta application or managing the application configuration in an IAC provider, like Terraform.

Okta configuration should be configured _out of band_ and is not provided in this repository.

Expand All @@ -64,10 +64,8 @@ To use Vault, the following environment variables must be configured:

| Variable | Purpose |
| ----------------- | ----------------------------------------------------------------- |
| VAULT_ROLE_NAME | The name of the Vault role to use to acquire credentials |
| VAULT_SECRET_MOUNT_PATH | The mount path of your Vault secrets mount |
| VAULT_SECRET_PATH | The path to the Vault secret containing your secrets |
| VAULT_AWS_AUTH_PATH | The path to the mount on your Vault instance that handles IAM authentication |
| KC_SECRET_MOUNT_PATH | The mount path of your Vault secrets mount |
| KC_SECRET_PATH | The path to the Vault secret containing your secrets |

The Vault secret should contain the following set of key-values - the values are examples and should be replaced as contextually appropriate:

Expand All @@ -78,6 +76,8 @@ okta_token={API TOKEN}

`{API_TOKEN}` must be replaced with an API token for Okta that has the `okta.apps.read` scope.

**The Lambda function does not handle authentication with Vault**. It is expected that you deploy the Lambda function with the [Hashicorp Vault Lambda Extension](https://developer.hashicorp.com/vault/docs/platform/aws/lambda-extension). How this Lambda extension is added depends on how you deploy your Lambda function and you should follow the instructions in the given link.

#### Environment Variables

We advise against using environment variables for secrets in AWS Lambda as they are persisted in plaintext. As such, your Okta API token may be leaked. If you would prefer to use environment variables, however, you must provide the following environment variables to your Lambda configuration:
Expand Down
179 changes: 0 additions & 179 deletions cli/credentials.go

This file was deleted.

Loading

0 comments on commit 5ff3e2f

Please sign in to comment.