Skip to content

Add tk CLI commands for keys, users, and policies#19

Open
natefikru wants to merge 3 commits intonatefikru/eng-3860-consensus-demo-rustfrom
natefikru/eng-3860-tk-cli-commands
Open

Add tk CLI commands for keys, users, and policies#19
natefikru wants to merge 3 commits intonatefikru/eng-3860-consensus-demo-rustfrom
natefikru/eng-3860-tk-cli-commands

Conversation

@natefikru
Copy link
Copy Markdown
Contributor

Summary

  • Add tk keys create/delete, tk users create/delete, tk policies create/delete CLI commands
  • Expose client() and organization_id() accessors on TurnkeySigner
  • All commands output JSON for script consumption
  • Replace the Rust consensus demo example with shell scripts that use these new CLI commands

New Commands

  • tk keys create --name <NAME> --curve <ed25519|secp256k1|p256> [--address-format <FORMAT>] [--tag <ID>]
  • tk keys delete --key-id <ID> [--delete-without-export]
  • tk users create --name <NAME> [--email <EMAIL>] [--api-key-name <NAME>] [--api-key-public-key <HEX>]
  • tk users delete --user-id <ID>
  • tk policies create --name <NAME> --effect <allow|deny> [--condition <CEL>] [--consensus <CEL>]
  • tk policies delete --policy-id <ID>

Test plan

  • All existing tests pass
  • New CLI commands compile with no warnings
  • E2e consensus demo runs entirely through shell scripts using tk CLI
  • Setup, sign, approve, teardown all succeed against local stack

Expose client() and organization_id() on TurnkeySigner. Add keys
create/delete, users create/delete, and policies create/delete
subcommands that call the Turnkey API via the Rust SDK. All commands
output JSON for script consumption. Move turnkey_client, serde_json,
hex, and turnkey_api_key_stamper to regular dependencies.
Delete main.rs. Add setup.sh and teardown.sh that use the new tk keys,
users, and policies commands. The entire demo now runs through shell
scripts and the tk CLI. Update README to document the new flow.
- keys delete: default delete_without_export to false (safe by default)
- policies create: reject allow policies with no condition or consensus
- setup.sh: write state.json incrementally, exclude private key from
  state, set umask 077 for agent.env, add ERR trap for partial cleanup
- teardown.sh: handle missing state.json and missing fields gracefully,
  pass --delete-without-export explicitly for key deletion
@natefikru natefikru changed the base branch from main to natefikru/eng-3860-consensus-demo-rust April 1, 2026 04:29
@natefikru
Copy link
Copy Markdown
Contributor Author

Note: the client() and organization_id() accessors on TurnkeySigner are needed because the existing pattern of adding dedicated wrapper methods for every API call doesn't scale. The current approve_activity and reject_activity methods on TurnkeySigner contain custom logic (e.g., silently swallowing already-rejected status) that arguably should not live in the signer layer. A follow-up PR will refactor those to use the client accessor directly and move error handling decisions to the CLI commands where they belong. The CLI should be a thin pass-through to the API, not a place for custom design choices.

@natefikru natefikru marked this pull request as ready for review April 1, 2026 04:50
}

impl From<AddressFormatArg> for AddressFormat {
fn from(a: AddressFormatArg) -> Self {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Is there a way to add a check to show we are not missing any address formats from the rust-sdk? That way the test will fail when we update the rust-sdk and get new address types

output["apiPublicKey"] = serde_json::Value::String(pk);
}
if let Some(sk) = api_private_key {
output["apiPrivateKey"] = serde_json::Value::String(sk);
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

we shouldn't be putting private keys in the output

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.

2 participants