Newsroom
ArcaLabs Research

Seamless Protection of Tool Secrets for AI Agents

Giving AI agents the power of local tools, without giving them the keys.

ArcaLabs Research 9 min read
Bash tools connect through Hardpan to a protected secrets vault

At ArcaLabs, we care deeply about the quality of the tools surrounding our agents. A tool should be easy for a model to discover, understand, and combine with the files already in its workspace. In our own harness, ordinary command-line interfaces have worked especially well for this.

The conventional way to authenticate a CLI, however, is to place a credential in an environment variable or configuration file readable by the process running it. That is not an acceptable default for an agent that may execute untrusted instructions or encounter prompt injection. This article describes Hardpan, an internal system that keeps stored credentials outside the agent process while preserving local CLI and filesystem workflows.

Why not just use an existing credential proxy?

Credential proxies are a strong fit when the natural unit of control is an outbound API request. Infisical's Agent Vault and its successor Agent Proxy, for example, keep credentials out of the agent process by intercepting outbound traffic and attaching credentials only to requests permitted by policy. That approach is deliberately interface-agnostic: because it operates at the network layer through the standard proxy environment variables and a trusted CA, existing CLIs, SDKs, and MCP servers keep working without per-tool wrappers.

Our reason for building something different was not that proxies cannot handle native CLIs. They can. It was that for our workloads the outbound request was not the only thing we wanted to write policy about. A single credential-backed CLI usually exposes both the capability we intend to grant and several we do not, and some of those are reachable without the tool making a distinguishable request at all. We wanted the approved executable and its argument vector to be part of the policy decision.

Hardpan therefore isolates the tool invocation itself, while retaining request-level brokering for SDKs and direct HTTP clients.

Why CLIs worked well for our agents

In our internal evaluations, bash tools outperformed their MCP-style counterparts on our task mix. Skills and CLI --help for command subtrees mean context is allocated on demand rather than always occupying the system prompt, so our agents can maintain more context over their workspace, and have more room to reason over more important items, such as deal materials.

Models may also have strong priors for common shell and CLI patterns, but we have not isolated that as the cause of the difference.

Why fully remote execution was a poor fit

Many of our tool calls are not self-contained. Agents combine API data with workspace files, and some tools write large results to disk for selective inspection with utilities such as rg.

A remote execution service can support this, but it needs one of three things: file transfer, a synchronized or persistent remote workspace, or shared storage. Each option adds latency, operational complexity, or a new consistency boundary. Splitting a tool so that its API call runs remotely while its file processing stays local is also possible, but often requires a custom wrapper and may not map cleanly onto third-party CLIs.

Our target was therefore:

  • normal shell and CLI ergonomics;
  • direct access to the local workspace;
  • no raw credential in the agent process, environment, argument vectors, or readable configuration;
  • explicit policy over the executable and argument vector, not only over the resulting request.
Hardpan architecture diagram 1
Remote execution does not necessarily copy every file before every call, but it does require a transfer, synchronization, or shared-storage boundary when the tool needs local workspace state. Protected local execution avoids that boundary.

The Hardpan boundary

Hardpan is named after the compacted layer of soil that can form beneath a physical sandbox. It mediates access to credential-backed tools inside each sandbox while moving credential lookup, policy enforcement, and credential-bearing execution out of the untrusted agent process.

Threat model

Hardpan treats everything running as the agent user—including code produced after prompt injection—as untrusted. It trusts the Linux kernel, the sandbox supervisor, Hardpan's daemon and policy, the selected tool binaries and their dependencies, and the external services being called.

For the user boundary to mean anything, the agent user must not have root access, sudo, a container-runtime socket, the ability to load eBPF programs, or capabilities such as CAP_SETUID, CAP_SETGID, CAP_SYS_PTRACE, CAP_BPF, or broad discretionary-access-control overrides. It must also be unable to modify Hardpan's daemon, policy, vault, approved executables, libraries, or trusted configuration.

Less obviously, the agent user must also be unable to write to:

  • the shim directory or anything else on its own PATH ahead of the shims;
  • any directory on a protected tool's executable search path;
  • configuration, state, or cache directories that a protected tool reads outside the workspace.

The boundary protects the stored credential from direct inspection by the agent. It does not prevent the agent from using an allowed capability, abusing an overly broad credential, or receiving sensitive data that an allowed API endpoint returns. Narrower capability definitions, response policy, and least-privilege credentials are required for that, and they are separate work.

It also does not, by itself, prevent the agent from reaching the credential through an approved tool. Two things have to be true for that. Policy has to bind a capability to an executable and a constrained argument vector, since most credential-backed CLIs ship a subcommand that simply prints the credential. And the protected tool has to not execute the agent's files, which means pinning its configuration discovery rather than letting it read the workspace. Both are per-tool work.

Three Linux identities

Hardpan uses three separate Linux user IDs:

  • agent owns the workspace in which model-selected tools operate;
  • hardpan owns the credential vault and runs the policy daemon;
  • hardpan-tool runs approved tools that need a credential.

When agent invokes a protected command, a shim sends a structured request to the hardpan daemon. The daemon authenticates the peer, validates the capability and its arguments, selects the executable named by policy, builds a clean environment, fetches the credential, and hands a scoped launch request to the transition path. Approved executables are root-owned and not writable by any of the three identities.

The UID-transition path

An ordinary Linux user cannot arbitrarily switch to another user ID, so the deployment needs a constrained supervisor, helper, or equivalent mechanism with only the privilege required for the transition. This is a load-bearing part of the trusted computing base and worth being specific about, at least as to shape.

There are two broad options: a setuid-root helper that the hardpan daemon executes, or a root-owned supervisor that the daemon reaches over a narrow, authenticated channel and that performs the transition itself. We prefer the second. A setuid binary is an executable sitting on the filesystem with a documented interface, and every environment variable, file descriptor, resource limit, and locale it inherits becomes part of an argument about whether it can be subverted. A supervisor that the untrusted identity cannot invoke at all does not require that argument.

Whichever shape is chosen, it must accept a policy-selected tool identifier rather than an arbitrary executable path or shell command, and it must drop all unnecessary capabilities before the tool runs.

PATH shims preserve the interface

The protection boundary should not make tools harder to use. Hardpan places small command wrappers, or shims, in an agent-unwritable directory at the front of the agent user's PATH. When the agent runs a protected command, normal shell path resolution selects the shim before an unprotected binary with the same name. The agent can change its own PATH and bypass a shim, but doing so must not provide a credential; the daemon remains the security boundary.

For example, when the agent runs gh auth status, the shim forwards a structured tool identifier, argument vector, working directory, and supported stream metadata to Hardpan. It must not concatenate these values into a shell command.

The interface is designed never to return the real credential, and never to place it anywhere the agent can read. Depending on the protected CLI, a protected launch can inject it through a narrowly constructed environment, a file descriptor, standard input, or another tool-specific mechanism.

The credential is never passed in the tool's argument vector. /proc/<pid>/cmdline is world-readable regardless of process ownership, so an argument-borne secret can be recovered by polling during the call. Environment variables are not readable across user IDs, which makes them a safer channel. They are still inherited by anything the tool spawns.

Output returns the same way. The daemon does not hand the tool's descriptors to the shim. It reads the tool's piped standard output and standard error, applies streaming redaction, and frames the bytes back over the socket for the shim to write out. That gives one place where response policy applies to CLI output.

Unix-domain socket authentication

Hardpan uses a Unix-domain socket for local IPC. Linux's SO_PEERCRED facility lets the daemon verify the user ID associated with the peer connection without introducing another long-lived API key. If the deployment uses a pathname socket, it should live in a broker-owned directory whose filesystem permissions restrict who can connect; Linux abstract-namespace sockets do not provide that pathname-permission check.

SO_PEERCRED records the peer's credentials as of connection setup. If the daemon uses the reported PID for anything beyond logging, note that PIDs can be reused between the check and the use; SO_PEERPIDFD (Linux 6.5 and later) returns a pidfd instead and avoids that race.

This check authenticates the immediate peer; it does not make the connection non-transferable. A malicious process already running as agent can call Hardpan directly or relay requests on behalf of another party because it is itself an authorized peer. Hardpan therefore assumes that any process under the agent identity can exercise the capabilities granted to that identity. Fine-grained policy, rate limits, audit logs, and approval gates—not the socket type—limit what those capabilities can do.

Hardpan architecture diagram 2

The raw credential exists only inside the trusted vault, broker, and launch path, and inside the protected tool process for as long as the call requires it. It is not sent to the agent process, and tool output is relayed by the daemon rather than written directly to the shim.

Separating the model call from the agent process

The model client itself also needs a credential. In our custom harness, the component exposed to the agent process does not hold that key; it sends a model request through a trusted local component that supplies the credential. The agent can control the request content within policy, but cannot read the provider key.

Other harnesses can use a local credential-injecting proxy or provider-issued short-lived, narrowly scoped credentials when available. The exact integration is harness-specific; the important property is that a long-lived model key is not placed in the untrusted process's environment or readable configuration.

SDKs and HTTP clients

Some tools expose an SDK or HTTP API rather than a CLI, and some CLIs cannot be constrained at the argument level. For these, Hardpan gives the client a placeholder key and a loopback base URL. A local adapter forwards the request over Hardpan's Unix socket, where the daemon maps it to a policy-defined upstream service.

Hardpan validates the request against the granted capability, removes any caller-supplied authentication, and injects the real credential before forwarding it. The agent can control the permitted method, path, and body, but not the credential or destination.

The adapter runs as agent and is not trusted. It is an ergonomic shim for clients that expect a base URL and an API key, not a security control: the placeholder key is not a secret and is not treated as one, and the loopback listener is reachable by any process running as agent. This is the one place where the peer authentication described above does not apply, because a loopback TCP connection has no SO_PEERCRED equivalent and the adapter cannot verify who called it. It does not need to. The adapter's own connection to the daemon is authenticated as agent, and the policy decision is made against that identity either way—which is exactly the assumption the shim path already makes.

This preserves normal SDK behavior and provides an escape hatch for APIs that would be impractical to reproduce as CLI subcommands, without exposing their credentials to the agent process.

Hardpan architecture diagram 3
The agent supplies request intent within a provider-specific capability. Hardpan retains control of the credential, upstream origin, and allowed request and response surface.

Rust and secret lifetime

We implemented Hardpan in Rust. Safe Rust removes many classes of memory-safety bugs from the control plane, although it does not prevent logic errors, unsafe-code defects, vulnerable dependencies, or policy mistakes. A self-contained binary also simplifies deployment into each sandbox; binary size and startup overhead should be treated as measured operational properties rather than guarantees of the language.

Credentials should be held for as little time as possible and copied as few times as practical. Libraries such as zeroize can ensure that cleanup writes to buffers they own are not optimized away by the compiler. That guarantee does not erase copies in registers, kernel buffers, third-party libraries, child processes, or previously copied environment strings.

Conclusion

Hardpan lets us keep the local CLI and filesystem interface that works well for our agents without placing long-lived raw credentials in the untrusted agent process. Linux user separation provides the core boundary; structured policy, a constrained UID-transition path, root-owned tool executables, filesystem and network restrictions, least-privilege credentials, and auditing make that boundary meaningful.

The design does not make an approved capability harmless, and it does not eliminate the need to audit the tools behind it. It gives us a general way to expose narrowly defined credential-backed capabilities while keeping the credentials themselves outside the agent's direct reach.