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
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added .github/assets/demo.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 6 additions & 6 deletions .github/workflows/chocolatey.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,13 @@ jobs:
if: ${{ github.event_name == 'workflow_dispatch' || (github.event.workflow_run.conclusion == 'success' && startsWith(github.event.workflow_run.head_branch, 'v')) }}
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

- name: Unshallow
run: git fetch --prune --unshallow

- name: Get latest release tag
uses: oprypin/find-latest-tag@v1
uses: oprypin/find-latest-tag@dd2729fe78b0bb55523ae2b2a310c6773a652bd1 # v1.1.2
with:
repository: ${{ github.repository }}
releases-only: true
Expand Down Expand Up @@ -60,21 +60,21 @@ jobs:
ls -la nuspec/chocolatey/tools/

- name: Choco Downgrade
uses: crazy-max/ghaction-chocolatey@v3
uses: crazy-max/ghaction-chocolatey@2526f467ccbd337d307fe179959cabbeca0bc8c0 # v3.4.0
with:
args: install chocolatey --version=1.2.1 --allow-downgrade -y -r --no-progress

- name: Pack Release
uses: crazy-max/ghaction-chocolatey@v3
uses: crazy-max/ghaction-chocolatey@2526f467ccbd337d307fe179959cabbeca0bc8c0 # v3.4.0
with:
args: pack nuspec/chocolatey/okta-aws-cli.nuspec --outputdirectory nuspec/chocolatey

- name: Choco Upgrade
uses: crazy-max/ghaction-chocolatey@v3
uses: crazy-max/ghaction-chocolatey@2526f467ccbd337d307fe179959cabbeca0bc8c0 # v3.4.0
with:
args: upgrade chocolatey

- name: Upload Release
uses: crazy-max/ghaction-chocolatey@v3
uses: crazy-max/ghaction-chocolatey@2526f467ccbd337d307fe179959cabbeca0bc8c0 # v3.4.0
with:
args: push nuspec/chocolatey/okta-aws-cli.${{ steps.version.outputs.nuget }}.nupkg -s https://push.chocolatey.org/ -k ${{ secrets.CHOCO_API_KEY }}
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
- name: Setup Go
uses: actions/setup-go@6edd4406fa81c3da01a34fa6f6343087c207a568
with:
go-version: 1.21
go-version-file: "go.mod"

- name: Setup Go Tools
run: make tools
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
- name: Set up Go
uses: actions/setup-go@6edd4406fa81c3da01a34fa6f6343087c207a568 #v3.5.0
with:
go-version: 1.21
go-version-file: "go.mod"

- name: Import GPG key
id: import_gpg
Expand Down
49 changes: 43 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -578,6 +578,23 @@ These settings are optional unless marked otherwise:
| Authorization Server ID | The ID of the Okta authorization server, set ID for a custom authorization server, will use default otherwise. Default `default` | `--authz-id [value]` | `OKTA_AWSCLI_AUTHZ_ID` |
| Custom STS Role Session Name | Customize STS Role Session Name. Default `okta-aws-cli` | `--aws-sts-role-session-name [value]` | `OKTA_AWSCLI_STS_ROLE_SESSION_NAME` |

### Interactive Selection with Fuzzy Search

When multiple IdPs or Roles are available, `okta-aws-cli` presents an interactive
picker with fuzzy search capabilities. This makes it easy to find the right
option even when you have many roles configured.

![Fuzzy Search Picker Demo](.github/assets/demo.gif)

**Features:**
- **Fuzzy search**: Type to filter options - matches are highlighted
- **Smart filtering**: Search is performed on the role/IdP name only (the part after the last `/`), not the full ARN
- **Keyboard navigation**: Use `↑`/`↓` arrows to navigate, `Enter` to select, `Esc` to cancel
- **Scroll indicators**: Shows count of items above/below when list is long

When typing `dev`, only roles containing "dev" in the role name will be shown,
with the matching characters highlighted.

### Friendly IdP and Role menu labels

When the operator has many AWS Federation apps listing the AWS IAM IdP ARNs can
Expand All @@ -591,18 +608,28 @@ and Roles can also be evaluated are regular expressions (see example below).
`$HOME/.okta/okta.yaml` as a configuration file and location. We will continue
that practice with read-only friendly okta-aws-cli application values.

#### Before
#### Before (without friendly labels)

```
? Choose an IdP: [Use arrows to move, type to filter]
? Choose an IdP:

> Type to filter...

> Fed App 1 Label
Fed App 2 Label
Fed App 3 Label
Fed App 4 Label

? Choose a Role: [Use arrows to move, type to filter]
(esc to cancel)

? Choose a Role:

> Type to filter...

> arn:aws:iam::123456789012:role/admin
arn:aws:iam::123456789012:role/ops

(esc to cancel)
```

#### Example `$HOME/.okta/okta.yaml`
Expand All @@ -620,18 +647,28 @@ awscli:
"arn:aws:iam::.*:role/operator": "Ops"
```

#### After
#### After (with friendly labels from okta.yaml)

```
? Choose an IdP: [Use arrows to move, type to filter]
? Choose an IdP:

> Type to filter...

> Data Production
Data Development
Marketing Production
Marketing Development

? Choose a Role: [Use arrows to move, type to filter]
(esc to cancel)

? Choose a Role:

> Type to filter...

> Admin
Ops

(esc to cancel)
```

### Configuration by profile name
Expand Down
72 changes: 72 additions & 0 deletions examples/picker_demo.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
//go:build ignore
// +build ignore

/*
* Copyright (c) 2026-Present, Okta, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

// This is a demo script to showcase the fuzzy search picker functionality.
// Run this demo to see how the picker works with example AWS IAM roles.
//
// Usage:
//
// go run examples/picker_demo.go
package main

import (
"fmt"
"os"

"github.com/okta/okta-aws-cli/v2/internal/picker"
)

func main() {
// Example AWS IAM roles with fake account IDs for demonstration
roles := []string{
"arn:aws:iam::123456789012:role/Admin",
"arn:aws:iam::123456789012:role/Developer",
"arn:aws:iam::123456789012:role/ReadOnly",
"arn:aws:iam::123456789012:role/DevOps-Engineer",
"arn:aws:iam::123456789012:role/Security-Analyst",
"arn:aws:iam::987654321098:role/Production-Admin",
"arn:aws:iam::987654321098:role/Production-Developer",
"arn:aws:iam::987654321098:role/Production-ReadOnly",
"arn:aws:iam::111222333444:role/Staging-Admin",
"arn:aws:iam::111222333444:role/Staging-Developer",
"arn:aws:iam::555666777888:role/QA-Tester",
"arn:aws:iam::555666777888:role/QA-Lead",
"arn:aws:iam::999000111222:role/Data-Engineer",
"arn:aws:iam::999000111222:role/Data-Scientist",
"arn:aws:iam::999000111222:role/ML-Engineer",
}

fmt.Println("=== Okta AWS CLI - Fuzzy Search Picker Demo ===")
fmt.Println()
fmt.Println("Tips:")
fmt.Println(" • Type to filter roles (searches role name, not full ARN)")
fmt.Println(" • Use ↑/↓ arrows to navigate")
fmt.Println(" • Press Enter to select")
fmt.Println(" • Press Esc to cancel")
fmt.Println()

selected, err := picker.Pick("Choose an AWS IAM Role:", roles)
if err != nil {
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
os.Exit(1)
}

fmt.Println()
fmt.Printf("✓ Selected: %s\n", selected)
}
41 changes: 30 additions & 11 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,43 +1,63 @@
module github.com/okta/okta-aws-cli/v2

go 1.21
go 1.24.2

require (
github.com/AlecAivazis/survey/v2 v2.3.6
github.com/BurntSushi/toml v1.4.0
github.com/aws/aws-sdk-go v1.55.5
github.com/cenkalti/backoff/v4 v4.1.3
github.com/charmbracelet/bubbles v1.0.0
github.com/charmbracelet/bubbletea v1.3.10
github.com/charmbracelet/lipgloss v1.1.0
github.com/go-jose/go-jose/v4 v4.0.4
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510
github.com/google/uuid v1.1.2
github.com/logrusorgru/aurora v2.0.3+incompatible
github.com/mattn/go-isatty v0.0.16
github.com/mattn/go-isatty v0.0.20
github.com/mdp/qrterminal v1.0.1
github.com/ompluscator/dynamic-struct v1.4.0
github.com/pkg/errors v0.9.1
github.com/sahilm/fuzzy v0.1.1
github.com/spf13/cobra v1.5.0
github.com/spf13/viper v1.14.0
github.com/stretchr/testify v1.9.0
github.com/tidwall/pretty v1.2.0
golang.org/x/net v0.34.0
golang.org/x/sys v0.29.0
golang.org/x/net v0.49.0
golang.org/x/sys v0.41.0
gopkg.in/dnaeon/go-vcr.v3 v3.1.2
gopkg.in/ini.v1 v1.67.0
gopkg.in/yaml.v2 v2.4.0
)

require golang.org/x/crypto v0.32.0 // indirect
require (
github.com/atotto/clipboard v0.1.4 // indirect
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
github.com/charmbracelet/colorprofile v0.4.1 // indirect
github.com/charmbracelet/x/ansi v0.11.6 // indirect
github.com/charmbracelet/x/cellbuf v0.0.15 // indirect
github.com/charmbracelet/x/term v0.2.2 // indirect
github.com/clipperhouse/displaywidth v0.9.0 // indirect
github.com/clipperhouse/stringish v0.1.1 // indirect
github.com/clipperhouse/uax29/v2 v2.5.0 // indirect
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect
github.com/lucasb-eyer/go-colorful v1.3.0 // indirect
github.com/mattn/go-localereader v0.0.1 // indirect
github.com/mattn/go-runewidth v0.0.19 // indirect
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect
github.com/muesli/cancelreader v0.2.2 // indirect
github.com/muesli/termenv v0.16.0 // indirect
github.com/rivo/uniseg v0.4.7 // indirect
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
golang.org/x/crypto v0.48.0 // indirect
)

require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/fsnotify/fsnotify v1.6.0 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/inconshreveable/mousetrap v1.0.1 // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
github.com/magiconair/properties v1.8.7 // indirect
github.com/mattn/go-colorable v0.1.12 // indirect
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/pelletier/go-toml v1.9.5 // indirect
github.com/pelletier/go-toml/v2 v2.0.6 // indirect
Expand All @@ -48,8 +68,7 @@ require (
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/subosito/gotenv v1.4.2 // indirect
golang.org/x/term v0.28.0 // indirect
golang.org/x/text v0.21.0 // indirect
golang.org/x/text v0.34.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
rsc.io/qr v0.2.0 // indirect
)
Loading