Skip to content

Commit

Permalink
update okta device code command and add subcommand & restructure doc
Browse files Browse the repository at this point in the history
  • Loading branch information
snigdhasjg committed Dec 1, 2023
1 parent 602e919 commit 8b869d3
Show file tree
Hide file tree
Showing 9 changed files with 136 additions and 100 deletions.
111 changes: 69 additions & 42 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,33 +16,73 @@ To invoke the cli, there are 2 option
1. Directly use `aws-fusion` command
2. Use it via [aws cli alias](https://docs.aws.amazon.com/cli/latest/userguide/cli-usage-alias.html) with `aws fusion`

## Commands
- [init](#usage-of-init)
- [open-browser](#usage-of-open-browser)
- store-iam-user-credentials
- [store](#usage-of-iam-user-credentials-store)
- [get](#usage-of-iam-user-credentials-get)
- [get-iam-user-credentials](#usage-of-get-iam-user-credentials)
- [generate-okta-device-auth-credentials](#usage-of-generate-okta-device-auth-credentials)
- [config-switch](#usage-of-config-switch)
- profile
- region
## Usage

---
## Usage of `init`
> Try `aws-fusion init --help` for detailed parameter
Initilize fusion app with creation of aws fusion alias
```commandline
usage: aws-fusion [<flags>] <command> ...
---
## Usage of `open-browser`
> Try `aws-fusion open-browser --help` for detailed parameter
Unified CLI tool for streamlined AWS operations, enhancing developer productivity
- Make AWS credentials available via aws profile
- Execute the script: `aws-fusion open-browser --profile my-profile`
- :tada: Your browser opens, and you are signed in into the AWS console
Flags:
-h, --help show this help message and exit
-v, --version Display the version of this tool
--debug Turn on debug logging
Command:
init [<flags>]
Initialize fusion app with creation of aws fusion alias.
open-browser [<flags>] [<args>]
Open a web browser for graphical access to the AWS Console.
-p, --profile PROFILE The AWS profile to create the pre-signed URL with
-r, --region REGION The AWS Region to send the request to
--clip Don't open the web browser, but copy the signin URL to clipboard
--stdout Don't open the web browser, but echo the signin URL to stdout
iam-user-credentials [<flags>] <sub-command>
IAM User credential helper.
iam-user-credentials get [<flags>] [<args>]
Retrieve IAM user credentials for AWS CLI profiles or application authentication.
--access-key ACCESS_KEY AWS access key
--account-id ACCOUNT_ID AWS Account ID for the name
--username USERNAME Username of a AWS user associated with the access key for the name
--credential-process Output the credential in AWS credential process syntax
iam-user-credentials store [<flags>] [<args>]
Store IAM user access key and secret key securely for streamlined authentication.
--access-key ACCESS_KEY AWS access key
--account-id ACCOUNT_ID AWS Account ID for the name
--username USERNAME Username of a AWS user associated with the access key for the name
--secret-key SECRET_KEY AWS secret key
okta [<flags>] <sub-command>
Generate AWS session credentials from Okta.
okta device-auth [<flags>] [<args>]
Generate AWS session credentials using SAML assertion from Okta device authentication.
--org-domain ORG_DOMAIN Full domain hostname of the Okta org e.g. example.okta.com
--oidc-client-id OIDC_CLIENT_ID The ID is the identifier of the client is Okta app acting as the IdP for AWS
--aws-acct-fed-app-id AWS_ACCT_FED_APP_ID The ID for the AWS Account Federation integration app
--aws-iam-role AWS_IAM_ROLE The AWS IAM Role ARN to assume
--credential-process Output the credential in AWS credential process syntax
config-switch [<flags>] <sub-command>
Switching between AWS config.
config-switch profile [<flags>]
Switch between available aws profile.
config-switch region [<flags>]
Switch between available aws region.
```

### Use cases
---
## Use case of `open-browser`
This only works with assume-role and federated-login, doesn't work with IAM user or user session.

#### IAM assume role
Expand Down Expand Up @@ -98,12 +138,7 @@ The docs
- https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html

---
## Usage of `iam-user-credentials store`
> Try `aws-fusion iam-user-credentials store --help` for detailed parameter
Store AWS credentials in system default credential store

### Use cases
## Usa case of `iam-user-credentials store`
To store IAM user credential in the system credential store for best security rather than plain text `~/.aws/credentials` file.

Manually the save the credential in the store using
Expand All @@ -116,12 +151,7 @@ aws-fusion iam-user-credentials store \
```

---
## Usage of `iam-user-credentials get`
> Try `aws-fusion iam-user-credentials get --help` for detailed parameter
Retrieve AWS credentials from system default credential store. Optionally plug the CLI to aws external credential process.

### Use cases
## Use case of `iam-user-credentials get`
Configure aws config file to use credential process

**Config file**
Expand All @@ -137,12 +167,7 @@ The docs
- https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-sourcing-external.html

---
## Usage of `generate-okta-device-auth-credentials`
> Try `aws-fusion generate-okta-device-auth-credentials --help` for detailed parameter
Simplifies the process of obtaining AWS session credentials using SAML assertion from Okta device authentication

### Use cases
## Use case of `okta device-auth`
Configure aws config file to use credential process

**Config file**
Expand All @@ -154,7 +179,7 @@ credential_process = aws-fusion generate-okta-device-auth-credentials --org-doma
```

---
## Usage of `config-switch`
## Use case of `config-switch`
A special of utility script to help easily switch `profile` and `region`

This works with 2 bash script, namely `_awsp` and `_awsr`
Expand All @@ -167,6 +192,8 @@ alias awsp="source _awsp"
alias awsr="source _awsr"
```

<img src="https://raw.githubusercontent.com/snigdhasjg/aws-fusion/main/doc/images/config-switch.png" width="300" alt="config-switch-image"/>

---
## License
This project is licensed under the MIT License - see the [LICENSE](./LICENSE) file for details.
Expand Down
14 changes: 8 additions & 6 deletions aws_fusion/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@
import logging
from importlib.metadata import version

from .commands import config_switch
from .commands import generate_okta_device_auth_credentials
from .commands import iam_user_credentials
from .commands import init
from .commands import open_browser
from .commands import (
init,
open_browser,
config_switch,
iam_user_credentials,
okta
)


def main():
Expand All @@ -21,7 +23,7 @@ def main():
init,
open_browser,
iam_user_credentials,
generate_okta_device_auth_credentials,
okta,
config_switch
]
[command.setup(subparsers, global_parser) for command in commands]
Expand Down
6 changes: 3 additions & 3 deletions aws_fusion/commands/config_switch.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@


def setup(subparsers, parent_parser):
summary = 'Switching between AWS config'
summary = 'Switching between AWS config.'
parser = subparsers.add_parser('config-switch', description=summary, help=summary, parents=[parent_parser])
switch_subparsers = parser.add_subparsers(dest='config_switch_command', required=True, help='Available AWS config switch commands')

profile_switch_summary = "Switch between available aws profile"
profile_switch_summary = "Switch between available aws profile."
profile_switch_parser = switch_subparsers.add_parser('profile', description=profile_switch_summary, help=profile_switch_summary, parents=[parent_parser])
profile_switch_parser.set_defaults(func=switch_profile)

region_switch_summary = "Switch between available aws region"
region_switch_summary = "Switch between available aws region."
region_switch_parser = switch_subparsers.add_parser('region', description=region_switch_summary, help=region_switch_summary, parents=[parent_parser])
region_switch_parser.set_defaults(func=switch_region)

Expand Down
40 changes: 0 additions & 40 deletions aws_fusion/commands/generate_okta_device_auth_credentials.py

This file was deleted.

6 changes: 3 additions & 3 deletions aws_fusion/commands/iam_user_credentials.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,16 @@ def setup(subparsers, parent_parser):
common_parser.add_argument('--account-id', required=False, help='AWS Account ID for the name')
common_parser.add_argument('--username', required=False, help='Username of a AWS user associated with the access key for the name')

summary = 'IAM User credential helper'
summary = 'IAM User credential helper.'
parser = subparsers.add_parser('iam-user-credentials', description=summary, help=summary, parents=[parent_parser])
credential_subparsers = parser.add_subparsers(dest='iam_user_credential_command', required=True, help='Available IAM User credential commands')

store_summary = 'Store IAM user access key and secret key securely for streamlined authentication'
store_summary = 'Store IAM user access key and secret key securely for streamlined authentication.'
store_parser = credential_subparsers.add_parser('store', description=store_summary, help=store_summary, parents=[parent_parser, common_parser])
store_parser.set_defaults(func=run_store)
store_parser.add_argument('--secret-key', required=True, help='AWS secret key')

get_summary = 'Retrieve IAM user credentials for AWS CLI profiles or application authentication'
get_summary = 'Retrieve IAM user credentials for AWS CLI profiles or application authentication.'
get_parser = credential_subparsers.add_parser('get', description=get_summary, help=get_summary, parents=[parent_parser, common_parser])
get_parser.set_defaults(func=run_get)
get_parser.add_argument('--credential-process', action='store_true', help='Output the credential in AWS credential process syntax')
Expand Down
2 changes: 1 addition & 1 deletion aws_fusion/commands/init.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@


def setup(subparsers, parent_parser):
summary = 'Initialize fusion app with creation of aws fusion alias'
summary = 'Initialize fusion app with creation of aws fusion alias.'
parser = subparsers.add_parser('init', description=summary, help=summary, parents=[parent_parser])
parser.set_defaults(func=run)

Expand Down
47 changes: 47 additions & 0 deletions aws_fusion/commands/okta.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import logging
from argparse import ArgumentParser

from ..aws.assume_role import AssumeRoleWithSamlCache
from ..okta.api import device_auth
from ..okta.api import saml_assertion
from ..okta.api import session_and_token
from ..okta.api import verification_and_token


LOG = logging.getLogger(__name__)


def setup(subparsers, parent_parser):
common_parser = ArgumentParser(add_help=False)
common_parser.add_argument('--org-domain', required=True, help="Full domain hostname of the Okta org e.g. example.okta.com")

summary = 'Generate AWS session credentials from Okta.'
parser: ArgumentParser = subparsers.add_parser('okta', description=summary, help=summary, parents=[parent_parser])
okta_subparsers = parser.add_subparsers(dest='okta_command', required=True, help='Available Okta commands')

device_auth_summary = 'Generate AWS session credentials using SAML assertion from Okta device authentication.'
device_auth_parser = okta_subparsers.add_parser('device-auth', description=device_auth_summary, help=device_auth_summary, parents=[parent_parser, common_parser])
device_auth_parser.set_defaults(func=run_device_auth)
device_auth_parser.add_argument('--oidc-client-id', required=True, help="The ID is the identifier of the client is Okta app acting as the IdP for AWS")
device_auth_parser.add_argument('--aws-acct-fed-app-id', required=True, help="The ID for the AWS Account Federation integration app")
device_auth_parser.add_argument('--aws-iam-role', required=True, help="The AWS IAM Role ARN to assume")
device_auth_parser.add_argument('--credential-process', action='store_true', help='Output the credential in AWS credential process syntax')


def run_device_auth(args):
assume_role_with_cache = AssumeRoleWithSamlCache(args.aws_iam_role)

if not assume_role_with_cache.does_valid_token_cache_exists():
LOG.debug('Credential cache not found, invoking SAML')
device_code, expires_in = device_auth(args.org_domain, args.oidc_client_id)
access_token, id_token = verification_and_token(args.org_domain, args.oidc_client_id, device_code, expires_in)
session_token = session_and_token(args.org_domain, args.oidc_client_id, access_token, id_token, args.aws_acct_fed_app_id)
saml_response, roles, session_duration = saml_assertion(args.org_domain, session_token)
assume_role_with_cache.assume_role_with_saml(saml_response, roles, session_duration)

if args.credential_process:
print(assume_role_with_cache.credential_process())
else:
print(assume_role_with_cache.environment_variable())


10 changes: 5 additions & 5 deletions aws_fusion/commands/open_browser.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,16 @@


def setup(subparsers, parent_parser):
summary = 'Open a web browser for graphical access to the AWS Console'
summary = 'Open a web browser for graphical access to the AWS Console.'
parser = subparsers.add_parser('open-browser', description=summary, help=summary, parents=[parent_parser])
parser.set_defaults(func=run)

parser.add_argument('-P', '--profile', default=os.getenv("AWS_PROFILE"), help="The AWS profile to create the pre-signed URL with")
parser.add_argument('-R', '--region', default=os.getenv("AWS_REGION", os.getenv("AWS_DEFAULT_REGION")), help="The AWS Region to send the request to")
parser.add_argument('-p', '--profile', default=os.getenv("AWS_PROFILE"), help="The AWS profile to create the pre-signed URL with")
parser.add_argument('-r', '--region', default=os.getenv("AWS_REGION", os.getenv("AWS_DEFAULT_REGION")), help="The AWS Region to send the request to")

no_browser_group = parser.add_mutually_exclusive_group()
no_browser_group.add_argument('--clip', action='store_true', help="don't open the web browser, but copy the signin URL to clipboard")
no_browser_group.add_argument('--stdout', action='store_true', help="don't open the web browser, but echo the signin URL to stdout")
no_browser_group.add_argument('--clip', action='store_true', help="Don't open the web browser, but copy the signin URL to clipboard")
no_browser_group.add_argument('--stdout', action='store_true', help="Don't open the web browser, but echo the signin URL to stdout")


def run(args):
Expand Down
Binary file added doc/images/config-switch.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 8b869d3

Please sign in to comment.