docs/documentation/platform/agent-proxy/quickstart.mdx
This tutorial takes you from an Infisical project to an agent making authenticated API calls through the Agent Proxy, with real credentials it never sees.
To follow along, you'll need:
17322 by default).gh CLI on the agent host, for the recommended verification in step 7. A curl fallback is provided, so this is not required.First, get a GitHub personal access token to broker:
GET /user, which any valid token can reach, so no permissions are needed here; later, grant only what your agent actually does.github_pat_… value. GitHub only shows it once.Then, in your Infisical project, create a folder for the agent (for example /coding-agent in the dev environment) and add a secret named GITHUB_PAT with that token as its value. It is a regular Infisical secret.
A proxied service maps a host to the secret the proxy applies. In the same folder, open the Add Secret dropdown and select Add Proxied Service, then work through the steps:
<Steps> <Step title="Pick the GitHub template"> The template fills everything in for you: the host `api.github.com` and a **Secret Substitution** rule that hands the agent a realistic `ghp_…` placeholder and swaps in the real token on the way out.

Here is how the pieces fit together. When your agent connects, it gets an environment variable `GITHUB_TOKEN` (the placeholder name the GitHub template uses) set to the fake `ghp_…` placeholder. The agent uses it like any GitHub token and sends `Authorization: Bearer <placeholder>`. As the request passes through the proxy, the placeholder is replaced with the real value of your `GITHUB_PAT` secret. The template scopes this swap to headers, since that is where GitHub expects the token; a substitution can also target the URL path, query, or body.


The proxy and the agent authenticate as two separate machine identities with opposite access. That split is the whole security model: the proxy can read your secrets, the agent never can.
The proxy identity reads the secrets.
<Steps> <Step title="Create the identity"> In your project, go to **Access Control → Machine Identities** and click **Add Machine Identity to Project → Create New**. Name it (for example `agent-proxy`) and create it.

Click **Add Client Secret**.

Save the **Client ID** and the **Client Secret**; you will pass both to the proxy in step 5.

Add a **Secrets** policy allowing both `Read Value` and `Describe Secret`. A [custom role](/documentation/platform/access-controls/role-based-access-controls) with the same policy, assigned to the identity, works too.
If you plan to broker [dynamic secrets](/documentation/platform/agent-proxy/proxied-services#using-dynamic-secrets) later, also allow `Manage Leases` on **Dynamic Secrets** while you are here. Only the proxy identity gets it; the agent identity never should.

The agent identity routes traffic but reads no secrets. It needs the Proxy permission and nothing else.


Remember this host's address; the next step points INFISICAL_AGENT_PROXY_ADDRESS at it. For production deployment, see Deployment.
# Scope: your project, plus the environment and folder from step 1
export INFISICAL_PROJECT_ID=<project-id>
export INFISICAL_ENVIRONMENT=dev
export INFISICAL_SECRET_PATH=/coding-agent
# The agent proxy to route through (from step 5)
export INFISICAL_AGENT_PROXY_ADDRESS=<proxy-host>:17322
```
# Scope: your project, plus the environment and folder from step 1
export INFISICAL_PROJECT_ID=<project-id>
export INFISICAL_ENVIRONMENT=dev
export INFISICAL_SECRET_PATH=/coding-agent
# The agent proxy to route through (from step 5)
export INFISICAL_AGENT_PROXY_ADDRESS=<proxy-host>:17322
```
# Scope: your project, plus the environment and folder from step 1
export INFISICAL_PROJECT_ID=<project-id>
export INFISICAL_ENVIRONMENT=dev
export INFISICAL_SECRET_PATH=/coding-agent
# The agent proxy to route through (from step 5)
export INFISICAL_AGENT_PROXY_ADDRESS=<proxy-host>:17322
```
The agent starts and behaves exactly as if you had launched it directly; nothing about it looks different. In its environment it finds GITHUB_TOKEN, set by connect to the fake placeholder, and uses it like a normal token. Its traffic now routes through the proxy: on calls to api.github.com the placeholder is swapped for the real token, and everything else passes through untouched. The next step makes that visible.
Each method below makes the same GET /user call to api.github.com. The client sends only the ghp_… placeholder that connect put in the environment; as the request passes through the proxy, the placeholder is swapped for the real value of your GITHUB_PAT secret. GitHub returns your account profile even though the real token never reached the client. That is the whole point: real authenticated work without the caller ever holding the credential.
> Run `gh api user` and show me the output.
[GitHub's `gh` CLI](https://cli.github.com/) reads `GITHUB_TOKEN` from the environment on its own, so the agent needs no token wiring; it just runs the command and GitHub returns your profile. Requires `gh` on the host where the agent runs.
```bash
infisical secrets agent-proxy connect -- gh api user
```
`gh` reads `GITHUB_TOKEN` automatically, so there is nothing else to pass. Requires `gh` on the host where you run this.
```bash
infisical secrets agent-proxy connect -- \
sh -c 'curl -sS https://api.github.com/user -H "Authorization: Bearer $GITHUB_TOKEN"'
```