Agentknock
Developer secrets on your phone, provided only to approved commands.
Agentknock lets command-line tools use secrets without storing long-lived credentials in agent configuration or project files. A paired mobile device authorizes each use. It can return environment values or perform operations such as Git signing without releasing a private key.
Early release · Share feedback
How Agentknock works
Agentknock delivers secrets from a paired mobile device when a command needs them. For example:
-
Run a command with the
gh-tokensecret: -
The paired mobile device displays the request. Approve the use of
gh-tokenfor this command. -
Agentknock runs
gh pr merge 123with access togh-token. The secret is available only to that execution and is not printed or written to disk.
Install the Agentknock client
Choose one of the following installation methods.
Use the installation script
The installation script selects the latest prebuilt release for the current
platform, verifies its published SHA-256 checksum, and installs agentknock
in ~/.local/bin:
|
Run the same command again to update Agentknock.
Use mise
Use the GitHub release through mise:
mise verifies the GitHub build attestation when one is available for the release artifact.
Run mise upgrade github:agentknock/agentknock-cli to update Agentknock.
Use npm
Run Agentknock without installing it globally:
To make the command persistently available, install it globally:
The npm package requires Node.js ^22.15.0 or >=24.0.0. Run
npm update --global agentknock to update Agentknock.
Use Nix
Run Agentknock without installing it in a profile:
To make the command persistently available, install it in your Nix profile:
Run nix profile upgrade agentknock-cli to update Agentknock.
Build from source with Cargo
Install Rust 1.89 or later, then build and install Agentknock from crates.io:
Run the same command again to update Agentknock.
Verify a release
Agentknock publishes each release as an immutable GitHub release. GitHub locks the release tag and attached files after publication and generates a release attestation for them. The release archives also have build-provenance attestations generated by the Agentknock release workflow.
Install the GitHub CLI, then download and verify the latest x86-64 Linux archive:
repository=agentknock/agentknock-cli
tag=
target=x86_64-unknown-linux-musl
archive=agentknock-.tar.gz
Use aarch64-unknown-linux-musl as target for an ARM64 Linux system or
aarch64-apple-darwin for an Apple Silicon Mac. On macOS, replace the
sha256sum command with shasum -a 256 --check. Release verification confirms
that the downloaded archive is part of the immutable release.
Build-provenance verification confirms that the Agentknock release workflow
built that archive from the identified source revision. Neither verification
determines whether the source code itself is safe.
The pinned Nix build can independently reproduce the release archive. On a system with Nix installed, check out the release and compare the resulting file:
A successful comparison means that the local build produced the same archive as the GitHub release.
Install the Agentknock mobile app
Google Play
Install the Agentknock app from Google Play.
App Store
The Agentknock app for iOS isn't available yet.
Get started
Agentknock includes its complete command-line reference in --help. Run
agentknock --help for an overview, or use --help with any command for
detailed instructions.
Choose the Agentknock directory
Agentknock stores pairing state in $HOME/.agentknock/pairing.json. If your
execution environment needs another location, set AGENTKNOCK_HOME to a
nonempty absolute UTF-8 directory path before pairing:
Use the same directory for pairing and subsequent commands. It must remain writable because Agentknock updates the pairing keys during use. Selecting another directory does not copy or move an existing pairing.
The global --agentknock-home option overrides the environment variable for
one command. Relative option paths are resolved against the current working
directory:
Neither setting changes the wrapped command's HOME. An existing
AGENTKNOCK_HOME is inherited normally; the option does not set or change it
for the wrapped command. With either override, Agentknock does not require
HOME and does not fall back to another directory if the selected location
is unusable.
Pair the client
Use the pairing address that you selected when you set up the mobile app. For
example, if the address is calm-river-lantern:
-
Start pairing on the client:
-
Confirm the full 12-digit verification code on the mobile device, then approve the pairing. If the code doesn't match, reject the pairing and run
agentknock pairing abort. -
After you approve the pairing, activate it on the client:
The client can now request secrets from the paired mobile device.
Run a command with secrets
The run command requires at least one secret. Repeat -s when a command
needs more than one. Use --reason to explain why each selected secret is
needed, such as API access, SSH authentication, or a signing operation. The
command and arguments already describe the action.
You can omit run and put its options directly after agentknock. For a
release script that needs both GitHub and Cloudflare access:
The explicit form is equivalent:
The -- separator is required. Agentknock passes the command and every
argument after the separator unchanged.
Agentknock waits for the paired mobile device to authorize the request and return the secrets before it starts the command. If the request is still waiting after 30 seconds, Agentknock writes a progress update with the elapsed time to standard error every 30 seconds. Press Ctrl-C to cancel the request.
Control environment-variable delivery
By default, an environment secret provides all its variables under their stored names. Delivery controls name both the secret and its stored variable, so they remain unambiguous when a command uses multiple secrets.
Use --only-env to select a subset, or --omit-env to exclude variables:
Repeat either option for more variables. You cannot combine --only-env and
--omit-env for the same secret.
Use --rename-env to give a selected variable a different name in the command
environment:
Use --stdin to send one stored variable to the command's standard input:
Agentknock sends the exact value without adding a newline, closes the input,
and does not add that variable to the command environment. Other variables
from the secret remain in the environment unless you restrict them with
--only-env. One command can receive at most one value on standard input.
Agentknock applies these controls separately to each secret before it combines their environment values. If multiple values have the same final name, their values must match.
Use SSH keys
An SSH secret keeps its private key on the paired device. Agentknock makes the selected public key available to the command through a temporary SSH agent. The temporary agent also makes keys from an existing SSH agent available. When SSH uses the selected key, Agentknock sends the exact authentication request to the device for a separate decision. Other keys continue to use the existing agent. Agentknock authentication currently supports Ed25519 and RSA keys.
Use the SSH secret with a direct connection:
The same setup works when Git uses an SSH remote:
The command can select at most one SSH secret. Agentknock puts that key first in the temporary agent and then lists keys from any existing agent. Agentknock never sends the selected private key to the client or command.
Use --no-ssh-passthrough when the temporary agent should not expose keys from
the existing agent:
This option also makes Git SSH signing fail if Git requests a different key. It does not prevent the command from using private-key files or another agent selected in SSH configuration.
Use --no-ssh-agent when the command should receive no SSH_AUTH_SOCK at all.
Agentknock Git signing remains available unless you also use --no-git-sign.
An IdentityAgent setting in SSH configuration takes precedence over
SSH_AUTH_SOCK. Set IdentityAgent SSH_AUTH_SOCK for a host that should use
the Agentknock agent.
Sign Git commits and tags
When Git requests a signature while running a command through Agentknock, Agentknock sends Git's exact signing payload to the device so it can show the commit or tag message for a separate decision. For commits, it also sends available repository, branch, and changed-path context to help identify the requested signature.
With Git configured to sign commits using SSH, wrap your usual command:
Use --no-git-sign when Agentknock should not provide Git signing. Agentknock
then leaves the existing Git signing configuration unchanged; that
configuration can still sign commits or tags independently.
A command can select at most one SSH secret. If Git has no configured
user.signingKey, Agentknock offers the selected SSH key as the default. If
Git explicitly selects another key, signing proceeds through the ordinary
ssh-keygen command unless you use --no-ssh-passthrough. It can use a key
file or a key from the existing SSH agent as usual. Agentknock does not change
gpg.format, signing policy, or the configured signing key. Git signing can
use SSH key types that Agentknock does not yet support for SSH authentication.
Use a network proxy
Agentknock uses HTTPS_PROXY for its secure WebSocket connection to the relay
and falls back to ALL_PROXY. The lowercase forms https_proxy and
all_proxy are also supported and take precedence over their uppercase forms.
Set NO_PROXY or no_proxy to exclude hosts from proxying. Proxy URLs can use
HTTP or HTTPS and can include HTTP Basic authentication credentials.
For example, connect through an HTTP proxy:
HTTPS_PROXY=http://proxy.example:8080
Manage secrets
Manage secrets primarily in the mobile app. The commands in this section contact the paired mobile device and wait for its response. During a long wait, Agentknock reports progress and elapsed time every 30 seconds.
List secrets
Request the secrets available to this client:
The command writes a JSON object to standard output. It maps each secret name to its type, description, and type-specific public metadata, such as environment variable names or an SSH public key. It never includes secret values. Progress and errors go to standard error, so you can process or redirect the JSON separately.
Upload secrets
Agentknock can migrate existing environment variables and SSH private keys to the mobile app. It reads values from the sources that you specify; the values do not appear in the command arguments.
To migrate a variable from the current environment:
To migrate all variables from a dotenv file:
To enter values without displaying them:
To read one variable from a file:
You can repeat and combine --from-env, --from-env-file, --from-file, and
--from-prompt. Use --from-env-file - to read dotenv data from standard
input, or --from-file NAME=- to read one value from standard input.
To upload an SSH private key in OpenSSH private-key format:
Use --from-ssh-key - to read the key from standard input. An SSH-key source
cannot be combined with environment-variable sources.
ssh-keygen can convert a legacy PEM key to OpenSSH format in place:
Agentknock rejects an encrypted private key unless you explicitly provide its
passphrase source. To enter the passphrase without displaying it, add
--passphrase-prompt. For a noninteractive upload, use
--passphrase-env NAME to read the passphrase from an environment variable.
Agentknock removes the passphrase protection locally and sends only the
resulting passphrase-free OpenSSH key. Agentknock's end-to-end encryption
protects the key in transit, and the mobile app stores it encrypted. The
passphrase is never sent to the mobile app.
An upload is a proposal, not an immediate change to the secrets on the mobile device. The command finishes after the mobile app confirms receipt of the proposal. Review and accept the proposal in the mobile app before the secret becomes available to this client.
By default, an upload proposes a new secret. Use --update to change the
values that you provide while retaining the other values in an existing
secret:
Use --replace to propose a complete replacement. Values that you don't
provide are removed if you accept the proposal. When you propose a new secret,
you can change its name before you accept it in the mobile app.
Uploading does not modify or delete source environment variables, private keys, or files. After you accept the proposal and verify the secret, remove old local copies that you no longer need.
Security
Agentknock uses a relay service to carry messages between the client and mobile device. The security design treats the relay as untrusted. The client and mobile app are both open source and protect messages with end-to-end encryption and authentication. After you verify a pairing, the relay cannot obtain secret values, read other protected contents, or alter an accepted protected message without detection. It can observe routing metadata, message sizes, timing, and traffic relationships, and it can deny service.
Starting a pairing is unauthenticated: anyone who knows the pairing address can send a request. Confirm the full 12-digit verification code before you approve a pairing on the mobile device. The code identifies the exact client that you intend to trust, including when multiple pairing requests are pending. It also detects substitution by the relay and lets the relay remain outside the trust boundary. Reject the pairing if you cannot confirm the complete code.
Agentknock never writes delivered secret values to disk. It opens the selected executable before asking the device to prepare the secrets, reports its path and hash when available, and revalidates it after approval. Linux executes a retained native executable directly. macOS must execute its path and therefore has a small final pathname race after revalidation.
For directly executed shebang scripts at most 16 KiB, Agentknock also sends the
entire source to the device for use in AI review by supporting devices. Invalid
UTF-8 sequences become replacement characters (�); hashing and execution use
the original bytes. Larger scripts omit the source and retain their full-file
hash. Source is sent before approval, may contain sensitive information, and
reaches the review service when included in AI review. Only the selected script
is captured; interpreter arguments and dependencies are not followed.
Agentknock is not a sandbox or privilege boundary. The approved command controls the secrets that it receives and can print them, write them to disk, or otherwise disclose them. Only approve secret access for commands that you trust to handle the values safely. Descendant commands and other processes with sufficient same-user inspection access might also observe them.
For the complete design, threat model, and limitations, read the Agentknock v1 cryptosystem and command execution design. The repository also includes reproducible symbolic analysis of the v1 cryptosystem, with claim-by-claim results, assumptions, and limitations. Report suspected vulnerabilities according to the security policy.
Supported platforms
Agentknock supports these client platforms:
| Platform | Release archive |
|---|---|
| x86-64 Linux | agentknock-x86_64-unknown-linux-musl.tar.gz |
| ARM64 Linux | agentknock-aarch64-unknown-linux-musl.tar.gz |
| Apple Silicon macOS | agentknock-aarch64-apple-darwin.tar.gz |
Each archive contains the Agentknock binary and license files. The Linux
archives contain a statically linked musl binary and do not require a system C
library. Linux command execution requires Linux 5.8 or later. SSH authentication
and Git signing also require a mounted /proc file system. The macOS archive
requires Apple Silicon and macOS 15 or later.
Agentknock supports WSL2 through its Linux environment. Use the archive that matches the WSL2 architecture. Native Windows clients and Intel Macs are not supported.
Documentation
- Client-device protocol defines the end-to-end messages and operations exchanged by a client and paired device.
- Client-relay protocol defines the WebSocket interface used by clients.
- Cryptosystem defines the end-to-end cryptographic construction and threat model.
- Command execution defines how the CLI selects, inspects, and starts an approved command.
The Rust API documentation describes the unstable interface for embedding Agentknock in applications. Direct library use is not currently recommended.
User documentation is available at agentknock.dev/docs.
Contribute
Contributions are welcome as bug reports, feature proposals, and design discussions in GitHub issues. The maintainers write the final implementation; pull requests can serve as prototypes or reproductions but are not merged. Read Contributing to Agentknock before you open an issue or pull request.
License
Agentknock is available under your choice of the Apache License 2.0 or the MIT License.