Skip to content
Merged
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
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
11 changes: 11 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file

version: 2
updates:
- package-ecosystem: "gomod" # See documentation for possible values
directory: "/" # Location of package manifests
schedule:
interval: "weekly"
28 changes: 28 additions & 0 deletions .github/workflows/go.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# This workflow will build a golang project
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-go

name: Go

on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]

jobs:

build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3

- name: Set up Go
uses: actions/setup-go@v4
with:
go-version: '1.23'

- name: Build
run: go build -v ./...

- name: Test
run: go test -v ./...
54 changes: 54 additions & 0 deletions .github/workflows/golangci-lint.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
name: golangci-lint
on:
push:
branches:
- main
pull_request:

permissions:
contents: read
# Optional: allow read access to pull request. Use with `only-new-issues` option.
# pull-requests: read

jobs:
golangci:
name: lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-go@v4
with:
go-version: '1.23'
cache: false
- name: golangci-lint
uses: golangci/golangci-lint-action@v3
with:
# Require: The version of golangci-lint to use.
# When `install-mode` is `binary` (default) the value can be v1.2 or v1.2.3 or `latest` to use the latest version.
# When `install-mode` is `goinstall` the value can be v1.2.3, `latest`, or the hash of a commit.
version: v1.63

# Optional: working directory, useful for monorepos
# working-directory: somedir

# Optional: golangci-lint command line arguments.
#
# Note: By default, the `.golangci.yml` file should be at the root of the repository.
# The location of the configuration file can be changed by using `--config=`
# args: --timeout=30m --config=/my/path/.golangci.yml --issues-exit-code=0

# Optional: show only new issues if it's a pull request. The default value is `false`.
# only-new-issues: true

# Optional: if set to true, then all caching functionality will be completely disabled,
# takes precedence over all other caching options.
# skip-cache: true

# Optional: if set to true, then the action won't cache or restore ~/go/pkg.
# skip-pkg-cache: true

# Optional: if set to true, then the action won't cache or restore ~/.cache/go-build.
# skip-build-cache: true

# Optional: The mode to install golangci-lint. It can be 'binary' or 'goinstall'.
# install-mode: "goinstall"
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,4 @@ dist/
*.key
*.crt

vendor/
.vscode
48 changes: 48 additions & 0 deletions .goreleaser.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# This is an example .goreleaser.yml file with some sensible defaults.
# Make sure to check the documentation at https://goreleaser.com

# The lines below are called `modelines`. See `:help modeline`
# Feel free to remove those if you don't want/need to use them.
# yaml-language-server: $schema=https://goreleaser.com/static/schema.json
# vim: set ts=2 sw=2 tw=0 fo=cnqoj

version: 2

before:
hooks:
# You may remove this if you don't use go modules.
- go mod tidy

builds:
- env:
- CGO_ENABLED=0
goos:
- linux
- windows
- darwin
- freebsd
main: ./cmd/aws-cli-oidc
ldflags:
- -s -w -X github.com/stensonb/aws-cli-oidc/version.Version={{.Version}} -extldflags -static

archives:
- format: tar.gz
# this name template makes the OS and Arch compatible with the results of `uname`.
name_template: >-
{{ .ProjectName }}_
{{- .Os }}_
{{- if eq .Arch "amd64" }}x86_64
{{- else if eq .Arch "386" }}i386
{{- else }}{{ .Arch }}{{ end }}
{{- if .Arm }}v{{ .Arm }}{{ end }}
# use zip for windows archives
format_overrides:
- goos: windows
format: zip

changelog:
sort: asc
filters:
exclude:
- "^docs:"
- "^test:"
8 changes: 3 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
NAME := aws-cli-oidc
VERSION := v0.6.0
REVISION := $(shell git rev-parse --short HEAD)
VERSION := $(shell git describe --tags --exact-match --match "v*.*.*" || git describe --match "v*.*.*" --tags || git describe --tags || git rev-parse HEAD)

SRCS := $(shell find . -type f -name '*.go')
LDFLAGS := -ldflags="-s -w -X \"github.com/openstandia/aws-cli-oidc/version.Version=$(VERSION)\" -X \"github.com/openstandia/aws-cli-oidc/version.Revision=$(REVISION)\" -extldflags -static"
LDFLAGS := -ldflags="-s -w -X \"github.com/stensonb/aws-cli-oidc/version.Version=$(VERSION)\" -extldflags -static"

DIST_DIRS := find * -type d -exec

Expand Down Expand Up @@ -55,5 +54,4 @@ release:

.PHONY: test
test:
go test -cover -v

go test -cover -v
47 changes: 36 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
# aws-cli-oidc

CLI tool for retrieving AWS temporary credentials using OIDC provider.
CLI tool for retrieving AWS temporary credentials using an OIDC provider.

This is a fork of [https://github.com/openstandia/aws-cli-oidc](https://github.com/openstandia/aws-cli-oidc), updated with:

* [AWS SDK for Go v2](https://github.com/aws/aws-sdk-go-v2)
* [GitHub Dependabot](https://github.com/dependabot)
* [golangci-lint](https://golangci-lint.run/)
* many other improvements

## How does it work?

Expand All @@ -22,15 +29,15 @@ Please refer the following diagrams how it works.

Before using this tool, the system administrator need to setup the following configuration.

- Identity Federation using SAML2/OIDC between AWS and the OIDC provider. See https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers.html
- Identity Federation using SAML2/OIDC between AWS and the OIDC provider. See https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers.html.
- Registration OIDC/OAuth2 client for this CLI tool in the OIDC provider. Note: The OIDC provider must allow any port to be specified at the time of the request for loopback IP redirect URIs because this tool follows [RFC 8252 OAuth 2.0 for Native Apps 7.3 Loopback Interface Redirection](https://tools.ietf.org/html/rfc8252#section-7.3).

Also depending on the federation type between AWS and the OIDC provider, requirements for the OIDC providers will change.

### Federation type: OIDC

- The OIDC provider only needs to support OIDC. SAML2 and OAuth 2.0 Token Exchange are not necessary. Very simple.
- However, the JWKS endpoint of the OIDC provider needs to export it to the Internet because AWS try to access the endpoint to obtain the public key and to verify the ID token which is issued by the provider.
- However, the JWKS endpoint of the OIDC provider needs to exported to the Internet for AWS to access the endpoint. This is required to obtain the public key and to verify the ID token which is issued by the IdP.

### Federation type: SAML 2.0

Expand All @@ -43,12 +50,13 @@ Also depending on the federation type between AWS and the OIDC provider, require
| ------------------------------------------------------------------------------ | ---- | ----------- |
| [Google account](https://accounts.google.com/.well-known/openid-configuration) | OK | - |
| [Keycloak](https://www.keycloak.org) | OK | OK (Note 1) |
| [Dex IdP](https://github.com/dexidp/dex) | OK | Not tested |

- Note 1: You need to use Keycloak 12 or higher that supports exchanging from access token to SAML2 assertion. Also, you need to enable Token Exchange feature.

## Install

Download from [Releases page](https://github.com/openstandia/aws-cli-oidc/releases).
Download from [Releases page](https://github.com/stensonb/aws-cli-oidc/releases).

## Usage

Expand All @@ -60,13 +68,14 @@ Usage:

Available Commands:
clear-secret Clear OS secret store that saves AWS credentials
completion generate the autocompletion script for the specified shell
completion Generate the autocompletion script for the specified shell
get-cred Get AWS credentials and out to stdout
help Help about any command
setup Interactive setup of aws-cli-oidc

Flags:
-h, --help help for aws-cli-oidc
-h, --help help for aws-cli-oidc
-v, --version version for aws-cli-oidc

Use "aws-cli-oidc [command] --help" for more information about a command.
```
Expand Down Expand Up @@ -96,20 +105,36 @@ export AWS_SESSION_TOKEN=FQoGZXIvYXdzENz.......

### Integrate aws-cli

[Sourcing credentials with an external process](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-sourcing-external.html) describes how to integrate aws-cli with external tool.
You can use `aws-cli-oidc` as the external process. Add the following lines to your `.aws/config` file.
[Sourcing credentials with an external process](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-sourcing-external.html) describes how to integrate aws-cli with external tool. You can use `aws-cli-oidc` as the external process.

For example, if your IdP, `myop`, has been setup as an [Identity Provider](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers.html) in the `123456789012` account, and the `arn:aws:iam::123456789012:role/developer` is configured to allow `AssumeRoleWithWebIdentity` from your IdP, you can authenticate with the `myop` provider, assuming the `arn:aws:iam::123456789012:role/developer` role for 12 hours, with an entry in your `.aws/config` file similar to:

```
[profile foo-developer]
credential_process=aws-cli-oidc get-cred -p myop -r arn:aws:iam::123456789012:role/developer -j -s -d 43200
```

Caution: The AWS temporary credentials will be saved into your OS secret store by using `-s` option to reduce authentication each time you use `aws-cli` tool.
Then, AWS CLI should work:
```
$ AWS_PROFILE=foo-developer aws sts get-caller-identity
{
"UserId": "AROA1T2W4XNSWEI3BS69H:aws-cli-oidc",
"Account": "123456789012",
"Arn": "arn:aws:sts::123456789012:assumed-role/developer/aws-cli-oidc"
}
```

Using the `-s` option, the AWS temporary credentials will be saved into your OS secret store. The next call to `aws-cli-oidc` with `-s` will attempt to reuse these credentials.

## Bugs?

Please report them via https://github.com/stensonb/aws-cli-oidc/issues

## Licence

Licensed under the [MIT](/LICENSE) license.

## Author
## Authors

- [Hiroyuki Wada](https://github.com/wadahiro)
- [Bryan Stenson](https://github.com/stensonb)
- [Hiroyuki Wada - github.com/wadahiro/aws-cli-oidc](https://github.com/wadahiro/aws-cli-oidc)
1 change: 1 addition & 0 deletions cmd/aws-cli-oidc/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
aws-cli-oidc
59 changes: 34 additions & 25 deletions cmd/aws-cli-oidc/clear_secret.go
Original file line number Diff line number Diff line change
@@ -1,25 +1,34 @@
package main

import (
"github.com/openstandia/aws-cli-oidc/lib"
"github.com/spf13/cobra"
)

var clearSecretCmd = &cobra.Command{
Use: "clear-secret",
Short: "Clear OS secret store that saves AWS credentials",
Long: `Clear OS secret store that saves AWS credentials.`,
Run: clearSecret,
}

func init() {
rootCmd.AddCommand(clearSecretCmd)
}

func clearSecret(cmd *cobra.Command, args []string) {
if err := lib.Clear(); err != nil {
lib.Writeln("Failed to clear the secret store")
lib.Exit(err)
}
lib.Write("The secret store has been cleared")
}
package main

import (
"fmt"

"github.com/spf13/cobra"
"github.com/stensonb/aws-cli-oidc/lib/log"
"github.com/stensonb/aws-cli-oidc/lib/secretstore"
)

var clearSecretCmd = &cobra.Command{
Use: "clear-secret",
Short: "Clear OS secret store that saves AWS credentials",
Long: `Clear OS secret store that saves AWS credentials.`,
RunE: clearSecret,
}

func init() {
rootCmd.AddCommand(clearSecretCmd)
}

func clearSecret(cmd *cobra.Command, args []string) error {
ss, err := secretstore.NewSecretStore(cmd.Context(), "")
if err != nil {
return err
}

if err := ss.Clear(cmd.Context()); err != nil {
return fmt.Errorf("failed to clear the secret store: %w", err)
}
log.Write("The secret store has been cleared")

return nil
}
Loading
Loading