A minimal utility for managing cli authentication with openstack more securely and conveniently
Project description
os-mfa
Convenient and secure OpenStack authentication and credential management inspired by broamski/aws-mfa
What problem does os-mfa solve?
First some quick background. OpenStack provides two main methods of setting credentials for programmatic authentication:
A) Environment variables set via 'openrc.sh' files
- ๐ก๏ธ Avoids storing passwords in plaintext on disk ๐
- ๐คฆ Session credentials are lost if you close or restart your terminal window ๐
- ๐ Sessions can't be shared/accessed across multiple terminal sessions ๐
- ๐ Not compatible with windows clients ๐
B) clouds.yaml configuration files
- ๐ Are accessible in every terminal session ๐
- ๐ช Are durable to restarts/shutdowns ๐
- ๐ Compatible and consistent user experience across platforms ๐
- ๐ Encourages credentials to be stored in plain text ๐
- โ Tokens expire after 12 hours and need to be manually refreshed and updated in clouds.yaml ๐
As we can see both have advantages and disadvantages. But what if we could have the best parts of both options?
๐ os-mfa ๐ฆ leverages the convenience and durability of using clouds.yaml
and automates the secure management of credentials and tokens
- ๐ก๏ธ Avoids storing passwords in plaintext on disk ๐
- ๐ Session credentials are accessible in all terminals sessions ๐
- ๐ช Are durable to restarts/shutdowns ๐
- ๐ Trivially switch between multiple authenticated OpenStack sessions ๐
- ๐ค Ensures native compatibility with the OpenStack ecosystem ๐
- ๐ Compatible and consistent user experience across platforms ๐
Quick start
Install os-mfa
pip install -U os-mfa
Download clouds.yaml
file from your OpenStack dashboard. For example
- Click API Access https://dashboard.catalystcloud.nz/project/api_access/
- Click Download OpenStack RC File on the top right
- Select OpenStack clouds.yaml File from the drop down
Place the file in your current working directory (.
) or an alternate location described by the docs
Linux
~/.config/openstack/clouds.yaml
/etc/openstack/clouds.yaml
Windows
C:\Users\you\.config\openstack\clouds.yaml
C:\ProgramData\openstack\clouds.yaml
E.g.
# /home/john/clouds.yaml
clouds:
catalystcloud:
auth:
auth_url: https://api.nz-hlz-1.catalystcloud.io:5000
project_id: 33735662374f4b7a9621631f2e7e5e15
project_name: acme-incorporated
user_domain_name: Default
username: john.smith@acme.com
password: 1ns3curE123!
identity_api_version: 3
interface: public
region_name: nz-hlz-1
Run os-mfa
$ export OS_CLOUD=catalystcloud
$ os-mfa
Authenticating 'john.smith@example.com' in project 'john-smith'
Enter Password:
MFA Code (Press enter to skip): 654321
Getting token...
$ openstack network list
+--------------------------------------+------------+--------------------------------------------+
| ID | Name | Subnets |
+--------------------------------------+------------+--------------------------------------------+
| f10ad6de-a26d-4c29-8c64-2a7418d47f8f | public-net | 5063aab1-aa08-48b2-b81d-730ac732fc51, |
| | | 8a7fe804-7fbe-43d0-aa1d-cfa03034ef22, |
| | | a1549e09-4176-4322-860c-cadc68608b48 |
+--------------------------------------+------------+--------------------------------------------+
If you close/restart or start a new terminal window, resume your openstack session simply by exporting $OS_CLOUD
again.
export OS_CLOUD=catalystcloud
What happened when we ran os-mfa?
os-mfa created a "long-term" configuration without any passwords or secrets.
- "long-term" configurations are distinguished with a suffix of
-long-term
- We do not use the long term configs with the openstack client tools.
The long term config used as a foundation for authentication by os-mfa which then:
-
Prompts the user for their password and totp token
-
Swaps the password and totp for an openstack auth token
-
Updates the original configuration to use the new token for authentication
The resulting clouds.yaml should look like this
# /home/john/clouds.yaml
clouds:
catalystcloud:
auth:
auth_url: https://api.nz-hlz-1.catalystcloud.io:5000
project_id: 33735662374f4b7a9621631f2e7e5e15
project_name: acme-incorporated
token: gAAAAABkTkGx4Dah37lkiGTSEe3-r[...]9dQCVTBRsKjg6NFIYgMYRdAk7TTvIPOaaOE
identity_api_version: 3
interface: public
region_name: nz-hlz-1
catalystcloud-long-term:
auth:
auth_url: https://api.nz-hlz-1.catalystcloud.io:5000
project_id: 33735662374f4b7a9621631f2e7e5e15
project_name: acme-incorporated
user_domain_name: Default
username: john.smith@acme.com
identity_api_version: 3
interface: public
region_name: nz-hlz-1
Going further
Switching between multiple cloud accounts and sessions
clouds:
project1-long-term:
region: nz-hlz-1
auth:
project_name: project1
username: john.smith@acme.com
# ...
project2-long-term:
region: nz-por-1
auth:
project_name: project2
username: john.smith@acme.com
# ...
After running os-mfa once for each project you can switch between them
OS_CLOUD=project1
OS_CLOUD=project2
Contributing
Nothing special to report, just raise a PR
Run tests
python -m unittest discover
Building Package
Source: https://realpython.com/pypi-publish-python-package/
python -m pip install pip-tools build twine bumpver
pip-compile pyproject.toml
python -m build
twine check dist/*
twine upload -r testpypi dist/*
twine upload dist/*
TODO
- โ๏ธ TBH I am probably going to port this back to python
- โ๏ธ Alert if no clouds.yaml found
- โ๏ธ Better error message if OS_CLOUD not set
- โ๏ธ CI/CD
- ๐ฆ Non-interactive mode
- ๐ฆ Sanitize long-term config better
- ๐ฆ Store and check expiry of token
- ๐ฆ Only reauthenticate if token is not valid
- ๐ฆ -f, --force cli option to force authentication
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.