> ## Documentation Index
> Fetch the complete documentation index at: https://forst-lang.org/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Invoke security

> Local transport, authentication, and header rules for calling Forst from Node.

Forst invoke is a local process boundary. It is designed for a Node application
and its local Forst server. Do not expose the invoke listener directly to the
public network.

## Default protections

On Unix, the invoke server listens on a mode `0600` Unix domain socket at
`.forst/invoke.sock` by default. Windows and `FORST_INVOKE_TRANSPORT=tcp` use
HTTP over loopback TCP instead. The server also checks the request `Host`
header, requires JSON for `POST /invoke`, limits concurrent invoke work, and
returns sanitized errors.

HMAC challenge-response auth is on by default. Set `FORST_INVOKE_AUTH=off` only
for local debugging. The server and Node clients log a startup warning every time
auth is disabled.

When Forst writes `.forst/invoke.ready`, it uses mode `0600`. The file contains
server metadata such as the URL, socket path, and auth generation. It does not
contain the token.

<Warning>
  `AllowNonLoopback` is an explicit opt-in for trusted deployments. It does not
  turn the local invoke protocol into a public API. Place a separately
  authenticated application API in front of Forst instead.
</Warning>

## Local transports

<Tabs>
  <Tab title="Unix (default)">
    A Unix domain socket at `.forst/invoke.sock` is the default local transport
    on non-Windows hosts. The socket has mode `0600`. Linux and macOS verify that
    the connecting peer has the same UID as the Forst process.

    `invoke.ready` advertises this transport through `socketPath`. The sidecar,
    `@forst/client`, CLI helpers, and generated `@forst/gen` transport read that
    path and dial the socket.
  </Tab>

  <Tab title="TCP fallback">
    Windows and `FORST_INVOKE_TRANSPORT=tcp` use HTTP over loopback TCP. The
    invoke server rejects non-loopback remote addresses.
  </Tab>
</Tabs>

## Authentication flow

Invoke RPC requests use a single-use challenge and an HMAC proof. The client
first requests `GET /invoke/challenge`. It then sends the nonce, current
generation, and an HMAC-SHA256 proof on the RPC request.

The proof binds the protocol version, generation, and nonce. A replayed nonce,
wrong generation, malformed proof, or proof from another token is rejected.
The server applies an exponential backoff for repeated failures from the same
peer.

The secret is a 32-byte token. Connect mode delivers it through the
`FORST_INVOKE_TOKEN` environment variable (base64url). The server sets this on
the `forst dev` process when it starts. Worker processes that attach to an
existing dev server must inherit `FORST_INVOKE_TOKEN` from the parent or receive
it explicitly.

In sidecar spawn mode, the child sends the secret through an inherited
`FORST_INVOKE_AUTH_FD` file descriptor instead. This keeps the secret out of the
ready file and avoids writing it to disk.

When `node.hostMode` is enabled, the Node app process (the host) may start
before the embedded invoke server inside the compiled Go program is ready. The
`forst dev` parent process opens a pipe, passes the read end into the Node host
as an inherited file descriptor (an open pipe handle the child receives at
startup), and relays auth lines from the Go program’s
`FORST_INVOKE_AUTH_FD` write end to the host’s `FORST_INVOKE_AUTH_RECV_FD` read
end. That way the host never reads a token file.

`.forst/invoke.ready` includes `tokenDelivery` (`env` or `handoff`) so clients
know which channel to use.

In a Node host process, call `prepareInvokeConnect()` from `@forst/cli/invoke`
at startup. It sets connect-mode env and listens on `FORST_INVOKE_AUTH_RECV_FD`.
Use `getInvokeAuthHandoff()` with your generated client's `resolveAuth` option
when auth arrives over the pipe.

<Note>
  Use the Forst sidecar transport for authenticated invoke requests. Do not
  build a raw `curl` request to `POST /invoke`: it cannot complete the
  challenge-response flow without the local secret.
</Note>

## Reserved request headers

The client owns these headers:

* `X-Forst-Invoke-Nonce`
* `X-Forst-Invoke-Generation`
* `X-Forst-Invoke-Proof`
* `X-Forst-Invoke-Token`

Forst removes caller-provided values for these names before it merges default
or per-request headers. This prevents application configuration from replacing
the authenticated proof. You may still send application headers such as
`Authorization`, `X-Request-Id`, and `X-Tenant-Id`.

## TLS and the local threat model

TLS is intentionally not used for the local invoke transport. A mode-`0600`
Unix socket plus same-user peer checks and proof authentication covers the
normal local development threat model. Loopback TCP still uses proof
authentication. Revisit TLS if invoke must bind beyond localhost or a
deployment requires encryption on loopback traffic.

## Test-only escape hatch

Set `FORST_INVOKE_AUTH=off` only for isolated tests or controlled CI fixtures.
It disables proof verification. The invoke server and Node transport log a
warning on startup whenever auth is off. Do not set it in development or
production application environments.

## Related

<CardGroup cols={2}>
  <Card title="Call Forst from Node" icon="https://mintcdn.com/forst/r5GJChnfkgCSJa-b/icons/typescript.svg?fit=max&auto=format&n=r5GJChnfkgCSJa-b&q=85&s=8a8c0cd7b4bf60c264d51f66d0f52e91" href="/docs/interop/node/call-forst" width="512" height="512" data-path="icons/typescript.svg">
    Configure generated clients and invoke functions.
  </Card>

  <Card title="Dev server" icon="server" href="/docs/workflow/dev-server">
    Run `forst dev` during local development.
  </Card>
</CardGroup>
