VM-to-VM Integration
Let one VM call another over HTTPS, with a generated key injected at the edge
The VM-to-VM integration (also called a *peer* integration) lets one of your
VMs make HTTPS requests to another — an agent calling an API served by a
second VM, a staging box hitting a shared service, two agents talking to each
other — without either VM ever holding a credential.
Under the hood it's an [HTTP Proxy integration](integrations-http-proxy)
whose target is another VM you own, created with the `--peer` flag. Two
things make it more than a plain proxy:
- **Generated key, never on the VM.** exe.dev generates an API key scoped to
the target VM, stores it server-side, and injects it at the network edge on
every request. The source VM can *use* the integration but can never read
the key — see [Where secrets live](integrations#where-secrets-live). The
target VM's auth proxy consumes the key; your server never sees it either.
- **Caller identity on delivery.** Requests arrive at the target with an
`X-Exedev-Source-Vm` header naming the calling VM. The platform *sets*
(never appends) this header after stripping anything the source VM sent,
so the caller cannot forge it. Use it to audit or route by caller.
## Setup from the UI
On the [Integrations page](/integrations), use the **HTTPS to another VM**
tile. Pick the target VM from the dropdown, optionally a port (the default
web port 8000 needs none), and attach it to the VMs that should be able to
call the target.
You can also type the target VM's name (or "vm-to-vm" or "peer") into the
[integration catalog](/integrations/catalog) search — matching one of your
own VMs offers this setup flow with that VM pre-selected as the target.
## Setup from the CLI
```
exe.dev ▶ integrations add http-proxy --name talk-to-bob --target https://bob.exe.xyz/ --peer --attach vm:alice
Added integration talk-to-bob (peer auth → bob)
```
The `--target` must be a VM you own (or have access to) on your exe.dev
domain. To reach a port other than 8000, put it in the target URL:
`https://bob.exe.xyz:3000/`.
The generated key shows up in `ssh-key list` with the label
`peer-<integration name>`; deleting the integration removes it.
## Example: two agents on two VMs
Say `bob` runs a small internal API on port 8000, and an agent on `alice`
needs to call it. Create the peer integration as above, then from `alice`:
```
exe.dev ▶ ssh alice curl -s http://talk-to-bob.int.exe.xyz/status
{"ok": true}
```
The request leaves `alice` with no credentials, picks up the generated key at
the edge, passes `bob`'s auth proxy, and arrives at bob's server on port 8000
looking like a normal request — plus the caller's name:
```
X-Exedev-Source-Vm: alice
```
Bob's server can use that header to decide what alice is allowed to do, tag
log lines by caller, or fan out behavior per peer. If several VMs attach the
same integration, they all reach `bob` through the same hostname and each is
identified by its own `X-Exedev-Source-Vm` value.
## Notes
- **Auth composes.** You can add `--header` or `--bearer` flags alongside
`--peer`; those headers are forwarded to the target VM in addition to the
automatic peer key (which travels in a reserved internal header the target
never sees). `--no-auth` conflicts with `--peer` — peer auth is always
injected.
- **Trust scope of `X-Exedev-Source-Vm`.** Traffic arriving through a peer
integration carries a platform-stamped value the calling VM cannot spoof.
But the header is informational on other paths: a human (or anything else
you've [shared](cli-share) the target VM with) could set it on their own
requests. If you make authorization decisions on it, keep the target VM
unshared or verify the request came in over the integration.
- **Ownership.** The target must be a VM you can access; the generated key is
scoped to exactly that VM (namespace `v0@<vm>.exe.xyz`) and is useless
anywhere else.
- **Same mechanics as HTTP Proxy.** Attachment, `int.exe.xyz` hostnames,
editing, and teams all work exactly as described in the
[HTTP Proxy integration](integrations-http-proxy) docs.