> For the complete documentation index, see [llms.txt](https://docs.euno.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.euno.ai/setup-configuration/account-settings/local-agents.md).

# Local Agents

A local agent lets Euno reach databases that run inside your private network — without opening inbound firewall ports. The agent connects **outbound** to Euno's relay, and Euno routes source integration traffic through the agent's encrypted tunnel to your database.

{% hint style="info" %}
Local agents are currently supported for **MySQL** and **SQL Server** integrations.
{% endhint %}

## Step 1: Create a local agent in Euno

1. Navigate to **Account Settings → Local Agents**.
2. Click **+ Create agent**.
3. Enter a **name** for the agent (e.g. `my-private-network-agent`) and optionally a **description** (e.g. `Production network - US East`).
4. Save. On the confirmation screen, copy the **Agent ID** and **Agent Secret**.

{% hint style="warning" %}
The Agent Secret is shown only once. Store it securely before closing the dialog — it cannot be retrieved afterwards.
{% endhint %}

## Step 2: Deploy the agent container

### Quick test

```bash
docker run -d --restart unless-stopped \
  -e AGENT_ID=<your-agent-id> \
  -e AGENT_SECRET=<your-agent-secret> \
  eunoai/euno-local-agent:latest
```

### Persistent setup (recommended)

Create a `docker-compose.yml` file on the machine that has access to your private network:

```yaml
services:
  euno-local-agent:
    image: eunoai/euno-local-agent:latest
    environment:
      AGENT_ID: <your-agent-id>
      AGENT_SECRET: <your-agent-secret>
    restart: unless-stopped
```

Then start the agent:

```bash
docker compose up -d
```

### Environment variables

| Variable       | Required | Description                              |
| -------------- | -------- | ---------------------------------------- |
| `AGENT_ID`     | Yes      | Agent UUID from the Euno Local Agents UI |
| `AGENT_SECRET` | Yes      | Secret from agent creation (shown once)  |

## Verifying the agent image (recommended)

Euno publishes the agent image signed, so you can confirm you are running exactly the image Euno built.

Pin to an immutable digest instead of the floating `:latest` tag:

```bash
# resolve the current digest
docker buildx imagetools inspect eunoai/euno-local-agent:latest --format '{{.Manifest.Digest}}'
# then reference it by digest in your compose/run
#   image: eunoai/euno-local-agent@sha256:<digest>
```

Save Euno's public signing key as `euno-agent.pub`:

```
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEtC8el1SduKyqU7Dgcc2crmhHkubI
H1gAS7PcerXGYgfgV98B3n9S1QPhGWOxEovBSChyV/+YNfAzTBUaagnn1A==
-----END PUBLIC KEY-----
```

Then verify the signature against it:

```bash
cosign verify --key euno-agent.pub \
  eunoai/euno-local-agent@sha256:<digest>
```

A successful verification confirms the image was signed by Euno's key and has not been altered.

## Step 3: Verify the connection

1. Go back to **Account Settings → Local Agents** and click **Refresh**.
2. The agent's status should change from **Disconnected** to **Connected**.

You can also verify by checking the container logs:

```bash
docker logs <container-name>
# Expected: agent <uuid> connected to relay
```

## Step 4: Configure a source to use the agent

When creating or editing a source (currently supported for **MySQL** and **SQL Server**), expand the **Advanced** section and select your agent from the **Local agent** dropdown (the **Need a local agent?** link under the credential fields takes you there). Set the hostname to your database server address as reachable from within your private network.

Click **Test & Save**. Euno will validate the connection through the agent before saving.

## Fetching credentials from your vault (secret handles)

Instead of typing database credentials into Euno, the agent can fetch them from your secret store at connection time. Euno stores only a **handle** (an opaque name you define); the value is fetched through the agent when a connection is tested or a sync runs, used in memory, and never persisted in Euno.

{% hint style="info" %}
Secret handles require an up-to-date agent image. Pull the latest image and restart the container before following this section; agents on older images keep tunneling normally but cannot serve handles.
{% endhint %}

### 1. Give the agent host access to your vault

The agent authenticates to Azure Key Vault with the host's **managed identity** — no credential is ever written into Euno or the agent's configuration.

1. Enable a system-assigned managed identity on the machine running the agent (for a VM: `az vm identity assign -n <vm> -g <resource-group>`, or the Identity blade in the portal). Container Apps, AKS, and Arc-enabled servers work through their platform identity equivalents.
2. Grant that identity the **Key Vault Secrets User** role on the vault (or on the individual secrets):

```bash
az role assignment create \
  --assignee-object-id <vm-identity-principal-id> --assignee-principal-type ServicePrincipal \
  --role "Key Vault Secrets User" \
  --scope $(az keyvault show -n <vault-name> --query id -o tsv)
```

For vaults using legacy access policies instead of RBAC, an access policy with secret **Get** permission is the equivalent. The vault must be reachable from the agent host; a private endpoint is recommended.

### 2. Create `secrets.yaml` on the agent host

```yaml
version: 1
secrets:
  - handle: sql-prod-password
    type: azure_kv
    directions:
      vault_uri: https://<your-vault>.vault.azure.net/
      secret_name: <secret-name>
      # version: optional; omit to always use the latest (recommended for rotation)
```

* `handle` — the name shown in the Euno UI. It is the only thing Euno stores.
* `type` — `azure_kv` (Azure Key Vault) is supported today; additional providers are planned.
* `directions` — where the secret lives. No credentials go in this file: the agent authenticates to the vault with the host's **managed identity**, which needs the **Key Vault Secrets User** role on the vault.
* The file is an **allowlist**: Euno can only fetch handles listed here.

Keep the file owned by root with `chmod 600`, and mount it read-only into the container (add to the `docker-compose.yml` above):

```yaml
    volumes:
      - /etc/euno/secrets.yaml:/etc/euno/secrets.yaml:ro
```

The agent reads the file at startup — restart the container after changing it. A malformed file (missing or duplicate handles, unknown provider type) makes the agent exit immediately with the reason in its logs, so mistakes surface at deploy time.

### 3. Pick handles in the source form

In the source's **Advanced** section, once a local agent is selected, each credential field gains a **from agent** dropdown listing the agent's handles. Picking one disables the matching inline field — the value now comes from your vault. Choose **Enter value manually** to switch back.

### Security notes

* The value travels from the agent to Euno through the agent's outbound encrypted tunnel — it is never exposed to your network and never written to Euno storage, logs, or error reports.
* Every fetch is written to the agent's container logs as an audit line (handle and outcome only, never the value), so your team can export access records from your own log pipeline.
* The agent refuses to start if long-lived cloud credentials (for example `AZURE_CLIENT_SECRET`) are present in its environment — vault access is by machine identity only.

## Managing agents

| Action | How                                                                                                         |
| ------ | ----------------------------------------------------------------------------------------------------------- |
| Rename | Click **⋯** next to the agent → **Edit**. Change the name in the form. This does not affect the connection. |
| Stop   | Stop the agent container. The UI will show **Disconnected** after a refresh.                                |
| Delete | Click **⋯** next to the agent → **Delete**. Update any sources that used the agent before deleting.         |

{% hint style="warning" %}
Deleting an agent clears the local agent selection and any credential references effectively using the deleted agent from sources that used it. Those sources cannot connect until you open them, select a new agent or enter credentials inline, and save.
{% endhint %}

## Troubleshooting

| Symptom                                                    | Fix                                                                                                                                                               |
| ---------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Status stays **Disconnected** after starting the container | Check that `AGENT_ID` and `AGENT_SECRET` are correct. Inspect container logs for connection errors.                                                               |
| Source run fails with "agent not connected"                | Ensure the agent container is running. Restart it if needed, then refresh the Local Agents page to confirm the status is **Connected** before re-running.         |
| Source run fails with "agent not found"                    | The agent was deleted from Euno. Create a new agent and update the source's Advanced settings to select it.                                                       |
| Source run fails with "Failed to connect to \[database]"   | Verify that the database hostname is reachable from the machine running the agent container (not the Euno cloud). Check firewall rules and credentials.           |
| `no matching manifest for linux/arm64/v8`                  | Add `platform: linux/amd64` to your `docker-compose.yml` under the `euno-local-agent` service. This applies when running on Apple Silicon Macs for local testing. |


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.euno.ai/setup-configuration/account-settings/local-agents.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
