Skip to content

Conversation

@travispaul
Copy link
Member

@travispaul travispaul commented Oct 14, 2025

Access Keys (utilized by the Manta S3 compat layer) were added to CloudAPI v9.11.0 and support was added to triton-go but not yet to node-triton.

This PR adds a triton accesskey command with get, list, create, delete, and update subcommands:

$ triton accesskey
Manage access keys.

Usage:
    triton accesskey [OPTIONS] COMMAND [ARGS...]
    triton accesskey help COMMAND

Options:
    -h, --help          Show this help.

  Output options:
    -H                  Omit table header row.
    -o field1,...       Specify fields (columns) to output.
    -l, --long          Long/wider output. Ignored if "-o ..." is used.
    -s field1,...       Sort on the given fields. Default is "created".
    -j, --json          JSON output.

Commands:
    help (?)            Help on a specific sub-command.
    get                 Show details for a specific access key.
    list (ls)           List access keys.
    create              Create a new access key.
    update              Update an access key.
    delete (rm)         Delete access key.

Listing keys (none created yet):

$ triton accesskeys # or `triton accesskey list`
ACCESSKEYID  STATUS  UPDATED

Creating a key:

$ triton accesskey create
ACCESSKEYID                       ACCESSKEYSECRET
3318520f5a9ea38c3345be9b7f5afa61  tdc_KzCt3UmUZas1PKq5gttM4TWAY6zIte64Z8kMvF7AfXzey0co

# Creating with status and description properties
$ triton  accesskeys create -s Inactive -d "Stage inactive key for later use"
ACCESSKEYID                       ACCESSKEYSECRET                                       STATUS    DESCRIPTION
df378ba6ed6de15781ebd5804b4b4555  tdc_EjU1mZGQlU29crDRj4lYhDArvQUy7Iz4UZn_-pyFw2L7NYHO  Inactive  Stage inactive key for later use

Listing keys:

$ triton accesskeys list # or `triton accesskeys`
ACCESSKEYID                       STATUS    UPDATED
3318520f5a9ea38c3345be9b7f5afa61  Active    2025-11-14T21:31:40.621Z
df378ba6ed6de15781ebd5804b4b4555  Inactive  2025-11-14T21:32:07.107Z

# long output
$ triton accesskey list -l
ACCESSKEYID                       STATUS    DESCRIPTION                       CREATED                   UPDATED
3318520f5a9ea38c3345be9b7f5afa61  Active    -                                 2025-11-14T21:31:40.621Z  2025-11-14T21:31:40.621Z
df378ba6ed6de15781ebd5804b4b4555  Inactive  Stage inactive key for later use  2025-11-14T21:32:07.107Z  2025-11-14T21:32:07.107Z

# JSON output
$ triton accesskey list -j
{"accesskeyid":"3318520f5a9ea38c3345be9b7f5afa61","status":"Active","created":"2025-11-14T21:31:40.621Z","updated":"2025-11-14T21:31:40.621Z"}
{"accesskeyid":"df378ba6ed6de15781ebd5804b4b4555","status":"Inactive","description":"Stage inactive key for later use","created":"2025-11-14T21:32:07.107Z","updated":"2025-11-14T21:32:07.107Z"}

# Specific fields:
$ triton accesskey list -o accesskeyid,status
ACCESSKEYID                       STATUS
3318520f5a9ea38c3345be9b7f5afa61  Active
df378ba6ed6de15781ebd5804b4b4555  Inactive

# No headers
$ triton accesskey list -H
3318520f5a9ea38c3345be9b7f5afa61  Active    2025-11-14T21:31:40.621Z
df378ba6ed6de15781ebd5804b4b4555  Inactive  2025-11-14T21:32:07.107Z

# Sorting
$ triton accesskeys -s status
ACCESSKEYID                       STATUS    UPDATED
3318520f5a9ea38c3345be9b7f5afa61  Active    2025-11-14T21:31:40.621Z
66cc1b0167470fbb81078839604f6f72  Expired   2025-11-14T21:34:42.949Z
df378ba6ed6de15781ebd5804b4b4555  Inactive  2025-11-14T21:32:07.107Z

Updating a key:

$ triton accesskey update  3318520f5a9ea38c3345be9b7f5afa61 description="Key for the Foo environment"
Updated access key 3318520f5a9ea38c3345be9b7f5afa61 (fields: description)

$ triton accesskey update 3318520f5a9ea38c3345be9b7f5afa61 status=Inactive
Updated access key 3318520f5a9ea38c3345be9b7f5afa61 (fields: status)

$ triton acesskeys -l
ACCESSKEYID                       STATUS    DESCRIPTION                       CREATED                   UPDATED
3318520f5a9ea38c3345be9b7f5afa61  Inactive  Key for the Foo environment       2025-11-14T21:31:40.621Z  2025-11-14T21:36:46.106Z
df378ba6ed6de15781ebd5804b4b4555  Inactive  Stage inactive key for later use  2025-11-14T21:32:07.107Z  2025-11-14T21:32:07.107Z
66cc1b0167470fbb81078839604f6f72  Expired   -                                 2025-11-14T21:34:42.949Z  2025-11-14T21:34:42.949Z

Getting a specific key:

$ triton accesskey get 3318520f5a9ea38c3345be9b7f5afa61
ACCESSKEYID                       STATUS    UPDATED
3318520f5a9ea38c3345be9b7f5afa61  Inactive  2025-11-14T21:36:46.106Z

# Accepts the usual options:

$ triton accesskey  get -j 3318520f5a9ea38c3345be9b7f5afa61
{"accesskeyid":"3318520f5a9ea38c3345be9b7f5afa61","status":"Inactive","description":"Key for the Foo environment","created":"2025-11-14T21:31:40.621Z","updated":"2025-11-14T21:36:46.106Z"}

$ triton accesskey get -H -o status,updated 3318520f5a9ea38c3345be9b7f5afa61
Inactive  2025-11-14T21:36:46.106Z

$ triton accesskey get -l 3318520f5a9ea38c3345be9b7f5afa61
ACCESSKEYID                       STATUS    DESCRIPTION                  CREATED                   UPDATED
3318520f5a9ea38c3345be9b7f5afa61  Inactive  Key for the Foo environment  2025-11-14T21:31:40.621Z  2025-11-14T21:36:46.106Z

Deleting a key:

$ tritonaccesskey delete 3318520f5a9ea38c3345be9b7f5afa61
Delete access key "3318520f5a9ea38c3345be9b7f5afa61"? [y/n] y
Deleted access key "3318520f5a9ea38c3345be9b7f5afa61"

This PR also adds the triton rbac accesskeys and triton rbac accesskey commands following the existing patterns of the rbac key{s} commands:

$ triton rbac accesskeys -h
List RBAC user access keys.

Usage:
    triton rbac accesskeys [OPTIONS] USER

Options:
    -h, --help          Show this help.

  Output options:
    -H                  Omit table header row.
    -o field1,...       Specify fields (columns) to output.
    -l, --long          Long/wider output. Ignored if "-o ..." is used.
    -s field1,...       Sort on the given fields. Default is "created".
    -j, --json          JSON output.

Where "USER" is an RBAC user login or id (a UUID).

$ triton rbac accesskey -h
Create, list, and delete RBAC user access keys.

Usage:
    triton rbac accesskey USER ACCESSKEYID
    triton rbac accesskey -c|--create [-s STATUS] [-D DESC] USER
    triton rbac accesskey -g|--get USER ACCESSKEYID
    triton rbac accesskey -u|--update [-s STATUS] [-D DESC] USER ACCESSKEYID
    triton rbac accesskey -d|--delete USER [ACCESSKEYID...]

Options:
    -h, --help                          Show this help.
    -j, --json                          JSON stream output.
    -l, --long                          Long/wider output. Ignored if "-o ..."
                                        is used.
    -o field1,...                       Specify fields (columns) to output.
    -f, --force                         Skip confirmation prompts.
    -D DESC, --desc=DESC, --description=DESC
                                        A short description for the access key.
    -s STATUS, --status=STATUS          Status for the access key.

  Action Options:
    -c, --create                        Create a new access key.
    -g, --get                           Get an access key.
    -u, --update                        Update an access key.
    -d, --delete                        Delete an access key.

Where "USER" is a full RBAC user "id", "login" name or a "shortid"

Listing keys (none created yet):

$ triton rbac accesskey subuser
ACCESSKEYID  STATUS  UPDATED

Creating a key for a subuser:

$ triton rbac accesskey -c subuser
Created access key ce809ab0dafe971e0348849415c07acc
Secret: tdc_BJhJZpZ8nXM0GHcO-PshJnpnyH0zz9Xur8fZ9FS9cFOCURZ4

# setting status/description properties during creation:
$ triton rbac accesskey -c -s Inactive -D "Some key" subuser
Created access key 07bd4922d9c2943c929576e49cab5e3f
Secret: tdc_9nIGh9rPWIOYkLE848x0k5w5zVww7OzSW7ggOGOAw7t7PsiB

Listing keys:

$ triton rbac accesskeys subuser
ACCESSKEYID                       STATUS    UPDATED
ce809ab0dafe971e0348849415c07acc  Active    2025-11-14T16:52:40.999Z
07bd4922d9c2943c929576e49cab5e3f  Inactive  2025-11-14T16:53:56.609Z

# long form
$ triton rbac accesskeys subuser -l
ACCESSKEYID                       STATUS    DESCRIPTION  CREATED                   UPDATED
ce809ab0dafe971e0348849415c07acc  Active    -            2025-11-14T16:52:40.999Z  2025-11-14T16:52:40.999Z
07bd4922d9c2943c929576e49cab5e3f  Inactive  Some key     2025-11-14T16:53:56.609Z  2025-11-14T16:53:56.609Z

# no headers, specific fields
$ triton rbac accesskeys subuser -Ho accesskeyid,status
ce809ab0dafe971e0348849415c07acc  Active
07bd4922d9c2943c929576e49cab5e3f  Inactive

# Sorting
$ triton rbac accesskeys subuser -H -s accesskeyid -o accesskeyid,status
07bd4922d9c2943c929576e49cab5e3f  Inactive
ce809ab0dafe971e0348849415c07acc  Active

# JSON
$ triton rbac accesskeys subuser -j
{"accesskeyid":"ce809ab0dafe971e0348849415c07acc","status":"Active","created":"2025-11-14T16:52:40.999Z","updated":"2025-11-14T16:52:40.999Z"}

Updating keys:

$ triton rbac accesskeys -u -s Active -D "Prod key" subuser ce809ab0dafe971e0348849415c07acc
Updated access key ce809ab0dafe971e0348849415c07acc (fields: status, description)

Getting a specific key

$ triton rbac accesskey subuser ce809ab0dafe971e0348849415c07acc
ACCESSKEYID                       STATUS  CREATED
ce809ab0dafe971e0348849415c07acc  Active  2025-11-14T16:52:40.999Z

# Long form
$ triton rbac accesskey -l subuser ce809ab0dafe971e0348849415c07acc
ACCESSKEYID                       STATUS  DESCRIPTION  CREATED                   UPDATED
ce809ab0dafe971e0348849415c07acc  Active  Prod key     2025-11-14T16:52:40.999Z  2025-11-14T16:58:29.171Z

# JSON
$ triton rbac accesskey -j subuser ce809ab0dafe971e0348849415c07acc
{"accesskeyid":"ce809ab0dafe971e0348849415c07acc","status":"Active","description":"Prod key","created":"2025-11-14T16:52:40.999Z","updated":"2025-11-14T16:58:29.171Z"}

# header and field options
$ triton rbac accesskey -Ho accesskeyid,description subuser ce809ab0dafe971e0348849415c07acc
ce809ab0dafe971e0348849415c07acc  Prod key

Deleting keys

$ triton rbac accesskey -d subuser ce809ab0dafe971e0348849415c07acc 07bd4922d9c2943c929576e49cab5e3f 
Delete 2 access keys (ce809ab0dafe971e0348849415c07acc, 07bd4922d9c2943c929576e49cab5e3f)? [y/n] y
Deleted access key "ce809ab0dafe971e0348849415c07acc"
Deleted access key "07bd4922d9c2943c929576e49cab5e3f"

Depends on:

LLM disclosure

Portions generated by: gpt-5-codex

I originally used codex to implement the first pass of some of the accesskeys sub commands, after refactoring and updating it to align with the cloudapi changes likely little of the original LLM generated code remains. Did not use codex for the rbac subcommands or tests.

@travispaul
Copy link
Member Author

travispaul commented Oct 15, 2025

Per an out-of-band discussion: this needs subuser support as well.

Update: sub user support was added via the rbac accesskey commands.

@travispaul travispaul marked this pull request as ready for review November 17, 2025 13:59
@travispaul travispaul requested a review from a team November 17, 2025 13:59
Copy link

@danmcd danmcd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Testing seems good. I've only one small question here.

danmcd
danmcd previously approved these changes Nov 17, 2025
@cneira
Copy link

cneira commented Dec 9, 2025

In the tests, I see that we can list temporary access keys (66cc1b0167470fbb81078839604f6f72), as shown by the status field being expired. We could also delete them, or let the periodic clean-up take care of those?

@cneira cneira self-requested a review December 9, 2025 13:46
@travispaul
Copy link
Member Author

@cneira I need to update the examples in the PR description to reflect the latest state but holding off to do that in case we have more changes in cloudapi.

The latest changes I've pushed here will show now show the credentialtype field by default:

$ triton accesskeys 
ACCESSKEYID                       STATUS    CREDENTIALTYPE  UPDATED
6ea33abf502acd6ee6cbe5534e1fe4e0  Expired   permanent       2025-11-20T20:19:06.252Z
f1678cfe5171e14959730b72107ed765  Active    permanent       2025-12-08T15:45:58.028Z
MSTS660D84478A1A37E8              Expired   temporary       2025-12-08T17:40:41.260Z
MSTSE39883C9CB5F9EFB              Expired   temporary       2025-12-08T17:40:41.854Z

and if requesting long output:

$ triton accesskeys -l
ACCESSKEYID                       STATUS    CREDENTIALTYPE  DESCRIPTION  CREATED                   UPDATED                   EXPIRATION
6ea33abf502acd6ee6cbe5534e1fe4e0  Expired   permanent       -            2025-11-20T19:25:29.070Z  2025-11-20T20:19:06.252Z  -
f1678cfe5171e14959730b72107ed765  Active    permanent       -            2025-12-08T15:45:58.028Z  2025-12-08T15:45:58.028Z  -
MSTSE39883C9CB5F9EFB              Expired   temporary       -            2025-12-08T17:40:41.854Z  2025-12-08T17:40:41.854Z  2025-12-08T18:40:41.853Z
MSTSE39883C9CB5F9EFB              Expired   temporary       -            2025-12-08T17:40:41.854Z  2025-12-08T17:40:41.854Z  2025-12-08T18:40:41.853Z

You can delete temporary access keys, this will remove them from UFDS and mahi.

You can also update the status and description just like permanent keys. Which is seems like something we may not want to allow

I see that we can list temporary access keys (66cc1b0167470fbb81078839604f6f72), as shown by the status field being expired.

The status field of permanent access keys can be updated and even set to Expired this is to mimic the functionality in AWS where permanent keys can't be automatically set to expire, but an external process can disable them by setting them to Expired. If the status changes to a non-Active status, they get removed from Mahi.

@cneira
Copy link

cneira commented Dec 9, 2025

@cneira I need to update the examples in the PR description to reflect the latest state but holding off to do that in case we have more changes in cloudapi.

The latest changes I've pushed here will show now show the credentialtype field by default:

$ triton accesskeys 
ACCESSKEYID                       STATUS    CREDENTIALTYPE  UPDATED
6ea33abf502acd6ee6cbe5534e1fe4e0  Expired   permanent       2025-11-20T20:19:06.252Z
f1678cfe5171e14959730b72107ed765  Active    permanent       2025-12-08T15:45:58.028Z
MSTS660D84478A1A37E8              Expired   temporary       2025-12-08T17:40:41.260Z
MSTSE39883C9CB5F9EFB              Expired   temporary       2025-12-08T17:40:41.854Z

and if requesting long output:

$ triton accesskeys -l
ACCESSKEYID                       STATUS    CREDENTIALTYPE  DESCRIPTION  CREATED                   UPDATED                   EXPIRATION
6ea33abf502acd6ee6cbe5534e1fe4e0  Expired   permanent       -            2025-11-20T19:25:29.070Z  2025-11-20T20:19:06.252Z  -
f1678cfe5171e14959730b72107ed765  Active    permanent       -            2025-12-08T15:45:58.028Z  2025-12-08T15:45:58.028Z  -
MSTSE39883C9CB5F9EFB              Expired   temporary       -            2025-12-08T17:40:41.854Z  2025-12-08T17:40:41.854Z  2025-12-08T18:40:41.853Z
MSTSE39883C9CB5F9EFB              Expired   temporary       -            2025-12-08T17:40:41.854Z  2025-12-08T17:40:41.854Z  2025-12-08T18:40:41.853Z

You can delete temporary access keys, this will remove them from UFDS and mahi.

You can also update the status and description just like permanent keys. Which is seems like something we may not want to allow

I see that we can list temporary access keys (66cc1b0167470fbb81078839604f6f72), as shown by the status field being expired.

The status field of permanent access keys can be updated and even set to Expired this is to mimic the functionality in AWS where permanent keys can't be automatically set to expire, but an external process can disable them by setting them to Expired. If the status changes to a non-Active status, they get removed from Mahi.

@cneira
Copy link

cneira commented Dec 9, 2025

@cneira I need to update the examples in the PR description to reflect the latest state but holding off to do that in case we have more changes in cloudapi.
The latest changes I've pushed here will show now show the credentialtype field by default:

$ triton accesskeys 
ACCESSKEYID                       STATUS    CREDENTIALTYPE  UPDATED
6ea33abf502acd6ee6cbe5534e1fe4e0  Expired   permanent       2025-11-20T20:19:06.252Z
f1678cfe5171e14959730b72107ed765  Active    permanent       2025-12-08T15:45:58.028Z
MSTS660D84478A1A37E8              Expired   temporary       2025-12-08T17:40:41.260Z
MSTSE39883C9CB5F9EFB              Expired   temporary       2025-12-08T17:40:41.854Z

and if requesting long output:

$ triton accesskeys -l
ACCESSKEYID                       STATUS    CREDENTIALTYPE  DESCRIPTION  CREATED                   UPDATED                   EXPIRATION
6ea33abf502acd6ee6cbe5534e1fe4e0  Expired   permanent       -            2025-11-20T19:25:29.070Z  2025-11-20T20:19:06.252Z  -
f1678cfe5171e14959730b72107ed765  Active    permanent       -            2025-12-08T15:45:58.028Z  2025-12-08T15:45:58.028Z  -
MSTSE39883C9CB5F9EFB              Expired   temporary       -            2025-12-08T17:40:41.854Z  2025-12-08T17:40:41.854Z  2025-12-08T18:40:41.853Z
MSTSE39883C9CB5F9EFB              Expired   temporary       -            2025-12-08T17:40:41.854Z  2025-12-08T17:40:41.854Z  2025-12-08T18:40:41.853Z

You can delete temporary access keys, this will remove them from UFDS and mahi.
You can also update the status and description just like permanent keys. Which is seems like something we may not want to allow

I see that we can list temporary access keys (66cc1b0167470fbb81078839604f6f72), as shown by the status field being expired.

The status field of permanent access keys can be updated and even set to Expired this is to mimic the functionality in AWS where permanent keys can't be automatically set to expire, but an external process can disable them by setting them to Expired. If the status changes to a non-Active status, they get removed from Mahi.

This is great, thank you!.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants