Skip to main content

Hacksaws

Hacksaws is an AWS login and IAM lifecycle CLI built for humans working beside agents. It can authenticate with MFA or AWS browser login, then optionally assume a role with a session policy so the credentials left on disk have a smaller blast radius than the credentials used to obtain them.

It also manages the accounts, targets, boundaries, reusable policies, IAM roles, and customer-managed policies used by that workflow. Every remote mutation is account-scoped, previewed, and recoverable where AWS permits it.

Install and run

Python 3.13 or newer is required. Run the published CLI without installing it:

uvx hacksaws --help

For development:

git clone https://github.com/rocketboosters/hacksaws.git
cd hacksaws
uv sync
uv run hacksaws --help
uv run test

uv run test is the repository quality gate. It runs formatting, linting, type checking, the warning-free test suite, and enforces at least 95% coverage.

Quick start

Browser login needs no pre-existing profile. Hacksaws creates the destination profile when needed:

hacksaws web in debug
aws sts get-caller-identity --profile debug

Regions accept canonical names and friendly aliases. Hacksaws explains the resolution and always persists the canonical AWS name:

hacksaws region explain oregon
# Canonical region: us-west-2

pk is an exact alias for web:

hacksaws pk in admin --name horizon

MFA login starts from persistent source credentials:

hacksaws mfa in admin --name horizon 123456

Omit the code in an interactive terminal for a hidden prompt, or use --mfa-code-stdin to read one line from standard input. JSON and other non-interactive use never prompts.

The source above is profile admin in ~/.aws-horizon. To write temporary credentials somewhere else, use --to LOCATION:PROFILE:

hacksaws mfa in admin --name horizon --to default:debug 123456

. and default both mean the default AWS directory or profile in their respective position.

Boundary sessions

A boundary assumes a role after authentication. With no --policy, the role's full permissions are used. Supplying a policy creates an intersected session: AWS allows only actions permitted by both the role and the session policy.

hacksaws web in debug \
  --role AgentSession \
  --policy CloudWatchReadOnlyAccess

Policies may be AWS/customer-managed policy names, ARNs, stored-policy names, or local JSON/YAML/TOML files. Hacksaws resolves and minifies the document before calling AssumeRole. AWS also applies a separate packed-policy limit; Hacksaws reports that limit explicitly but does not rewrite policy semantics.

Save role/policy/duration combinations as boundaries and full login presets as targets:

hacksaws boundary add cloudwatch AgentSession \
  --account prod --policy CloudWatchReadOnlyAccess --duration 1h

hacksaws target add hacw \
  --source-account prod --source-profile admin \
  --source-location horizon --boundary cloudwatch

hacksaws web in +hacw
# Equivalent explicit spelling:
hacksaws web in --target hacw

A successful login can also teach Hacksaws the complete reusable target:

hacksaws web in debug --role AgentSession \
  --policy CloudWatchReadOnlyAccess --save=debug-agent
hacksaws web in +debug-agent

Use bare --save in an interactive terminal to choose the name after the credentials are committed. Automation must use --save=NAME or --save-name NAME. See Saving login workflows for account discovery, advanced naming, local-policy storage, and recovery from a successful session whose configuration save did not complete.

Durations accept forms such as 15m, 15minutes, 1h, hour, 600s, and 600seconds. Rigid aliases --htl, --mtl, and --stl accept floating-point hours, minutes, and seconds; sub-second results round to whole seconds.

If credentials are already logged in, constrain them without repeating the authentication step:

hacksaws assume admin --name horizon \
  --role AgentSession --policy CloudWatchReadOnlyAccess \
  --to default:agent

For a destination profile in the same AWS location, hacksaws assume SOURCE DEST --role ... is the short form of --to-profile DEST.

The destination is always explicit. The source is removed after a successful handoff unless --keep-source is deliberate; use --self for an intentional in-place replacement. See Assume a role for destination, confirmation, ECR, and automation safeguards.

Inspect before acting

The human views are compact tables. Add global --json for automation and --no-color when ANSI styling is undesirable:

hacksaws status
hacksaws profile list
hacksaws profile list --verify
hacksaws iam list --profile admin --wide
hacksaws cache status
hacksaws config show
hacksaws history list --since 24h

iam list verifies live ownership tags within the canonical /hacksaws/ paths by default. That fast scope can miss adopted resources elsewhere, custom or changed paths, and untagged legacy resources; add --all-account for the comprehensive supported-resource scan. Add --details when dependency information is worth the additional AWS calls. Human terminals receive delayed progress on stderr while stdout remains safe to pipe; use --progress to force plain milestones or --no-progress to suppress them. JSON mode is always quiet until its single result envelope.

Local history records redacted command families, outcomes, timings, and validated identifiers—not raw arguments, output, prompts, paths, policy documents, or credentials. Use hacksaws history status to inspect retention and health. See Local command history for the full security contract, filters, exports, and clearing behavior.

Global output flags may appear anywhere before --:

hacksaws --json iam policy list
hacksaws iam policy list --color never

Remote IAM lifecycle

iam and remote are exact aliases. Credential selectors belong on terminal commands, so the following is intentionally supported:

hacksaws iam policy create agent.yaml --profile admin --dry-run
hacksaws iam policy create agent.yaml --profile admin --yes
hacksaws iam role create AgentSession --profile admin --trust-caller --dry-run

Create commands never silently overwrite a differing resource. An identical resource reports NO CHANGE; a difference reports CONFLICT. Use the normal update command, or deliberate create --replace plus confirmation.

Normal remote IAM mutations accept --dry-run. A dry run performs discovery, validation, collision checks, and planning, but creates no recovery journal and changes neither AWS nor local state. Recovery continue and rollback commands resume an already-journaled operation and therefore do not accept --dry-run.

Mutation previews and results use one credential-free contract: exact resource identity and ownership, scalar before/after changes, ordered AWS actions, dependencies, warnings, confirmation, applied actions, resource IDs/ARNs, console links, and recovery journal IDs. Policy documents and tag values are represented only by non-reversible summaries.

Leave No Trace cleanup

Cleanup deletes only resources whose Hacksaws ownership can be established in the selected account. A pattern, --all, --smoke, or --smoke-run is mandatory. With no type flags, all supported types are considered.

hacksaws cleanup "*ServiceBuzz*" --policies --profile admin --dry-run
hacksaws cleanup --all --profile admin --dry-run
hacksaws cleanup --smoke --profile admin --yes

--roles, --policies, and --group-grants narrow resource types. --created and --adopted narrow ownership origin. Cross-retained dependencies require explicit --cascade, --remove-boundaries, or --remove-from-instance-profiles consent. hacksaws iam cleanup and hacksaws remote cleanup use the same planner and executor.

Log out safely

Logout removes Hacksaws-managed live credentials without contacting an AWS logout endpoint. It never stores the intermediate MFA-authenticated credentials used to assume a boundary role.

hacksaws logout debug
hacksaws logout --all
hacksaws logout --all --except "default:prod*" --except "+hacw"

Tracked ECR logins are removed by default; use --keep-ecr deliberately. Unknown external profiles are never altered.

Credential threat model

The MFA workflow involves three distinct credentials:

  1. Persistent unauthenticated source credentials remain on the device. Give them only the permissions needed to perform MFA/session bootstrap, because a local agent may be able to read them.
  2. MFA-authenticated intermediate credentials exist only while login and any ECR login are being completed. They are not backed up when a boundary is used.
  3. Boundary credentials are the role/session-policy credentials written to the destination for the user or agent.

Browser login similarly uses its authenticated credentials only to complete the requested workflow, then leaves the final requested credentials at the target.

Configure an assumable role

The role trust policy must allow the login identity to call sts:AssumeRole. Hacksaws can generate the common caller-specific policy:

hacksaws iam role create AgentSession --trust-caller --profile admin

The equivalent trust statement is:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": { "AWS": "arn:aws:iam::123456789012:user/alice" },
      "Action": "sts:AssumeRole"
    }
  ]
}

The caller also needs an identity policy permitting sts:AssumeRole on the role. A group cannot be an IAM trust principal. Hacksaws can instead grant a group through a managed group policy, or expand the group's current users into individual trust principals. See the trust guide before choosing between those models.

Learn more

Run hacksaws COMMAND --help at any level. The CLI is the canonical command reference and includes selector, safety, confirmation, and repair guidance.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

hacksaws-0.4.1.tar.gz (312.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

hacksaws-0.4.1-py3-none-any.whl (260.8 kB view details)

Uploaded Python 3

File details

Details for the file hacksaws-0.4.1.tar.gz.

File metadata

  • Download URL: hacksaws-0.4.1.tar.gz
  • Upload date:
  • Size: 312.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for hacksaws-0.4.1.tar.gz
Algorithm Hash digest
SHA256 a8d9a0d927bb7ac8de1461e386a951fa6fe75ece62ff67c764d1a94311a53545
MD5 fc3c388db13cc8621ed3843dbe23e2cf
BLAKE2b-256 7ca2072ba04cfda63b030f4a2d733282c9e7afda4e4846bdd3216ad2f9eda882

See more details on using hashes here.

Provenance

The following attestation bundles were made for hacksaws-0.4.1.tar.gz:

Publisher: publish.yaml on rocketboosters/hacksaws

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file hacksaws-0.4.1-py3-none-any.whl.

File metadata

  • Download URL: hacksaws-0.4.1-py3-none-any.whl
  • Upload date:
  • Size: 260.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for hacksaws-0.4.1-py3-none-any.whl
Algorithm Hash digest
SHA256 0e50154b5c1e92aaf294ac632b9be335418bcef1fc8c508491ad67a19e222f16
MD5 915830974e673d8359822ef34ac9337d
BLAKE2b-256 b24db32a45a06ad991b9f64faf2bbc4425d610391a7700bad6f7d0f6da3c4333

See more details on using hashes here.

Provenance

The following attestation bundles were made for hacksaws-0.4.1-py3-none-any.whl:

Publisher: publish.yaml on rocketboosters/hacksaws

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page