# Connections and scope

> A connection is one vendor account given to Graft: scheme, credential and host set. Scope is the connections an agent may use.

Source: https://docs.getgraft.ai/graft/concepts/connections-and-scope

A **connection** is one vendor account you have given Graft. It has three parts: an **auth scheme** (how the proxy presents the credential to the vendor), a **credential** (what the proxy injects), and a **host set** (the hosts the credential may be sent to, and nothing else). It belongs to you, not to an agent: GitHub is entered once however many harnesses you run.

Credentials are write-only after entry. The console shows when a credential was set and never what it is.

## Where the credential lives

Every connection comes from a **provider**, which decides how you connect the vendor and what happens to a call. The **keyring** is every deployment's provider and covers every vendor: you enter the secret in the console, Graft stores it encrypted, and the proxy injects it. On Graft Cloud a second provider stands in front of it for the vendors Pipedream Connect offers, Gmail first: you connect with one click, Pipedream holds the vendor's token, and every call is relayed through Pipedream's proxy, which adds the token on the way. Graft then stores no credential for the connection at all, only the id of the account at Pipedream. The card says which provider a connection came through; a connection with no badge is the keyring's.

## The scheme

The scheme decides which secret fields the form asks for and how the proxy carries the credential.

| Scheme | The console calls it | You enter |
| --- | --- | --- |
| `api_key_header` | API key in a header | API key |
| `api_key_query` | API key in a query parameter | API key |
| `bearer` | Bearer token | Token |
| `basic` | Username and password | Username, Password |
| `oauth2_client_credentials` | OAuth2 client credentials | Client id, Client secret |
| `oauth_authorization_code` | OAuth consent (a client you register) | Client id, Client secret, then a consent in a popup |
| `unleashed_hmac` | Unleashed HMAC (API id and key) | API id, API key |
| `snowflake_keypair_jwt` | Snowflake key-pair JWT | Private key, and an optional passphrase |

A connection made through Pipedream records `relay` as its scheme (a connection through your own API gateway records `gateway`): not something you choose, but how its calls leave, relayed rather than signed.

Some schemes carry non-secret parameters beside the credential: a header name and an optional prefix, a query parameter name, a token URL and scopes, an authorize URL. The agent proposes these from the vendor's documentation; you can edit them on the form.

## The host set

The **primary host** is an https base URL that vendor-relative paths resolve against, `https://api.github.com` say. **Additional hosts** are hostnames a vendor's API spans, for an SDK that reaches several. The primary's own host is always in the set.

Every host must be public. Private, loopback, link-local, cloud-metadata and internal addresses are refused when the agent proposes them, refused again as you type them on the form, and refused a third time by the proxy at call time, on the address the name actually resolved to. A credential is only ever sent to a public host.

The proxy pins every call to this set. A request for a host outside it is refused, and a redirect is followed only within it, and only when the deployment has turned redirects on.

## Scope

**Scope** is the connections one agent may use. It is edited on the agent's page under **Scope**, saved whole with **Save scope**, and in effect on the agent's next call.

Scope is where the security property lives. The capability token minted for each run names the agent and the connections in its scope, so an authored tool running for one agent cannot reach a connection that agent was never given, whatever its code says.

A connection reaches an agent's scope two ways. When the agent proposes it with `request_connection` and you connect it in the console, it lands in that agent's scope alone. A connection you add yourself under **Connections → Add connection**, or that another agent proposed, reaches an agent when you tick it in that agent's Scope.

Each connection in scope also gives the agent an `execute__<connection id>` tool, the low-level way to run code against that connection while a tool is being authored. `acquire` takes a `connectionId` and refuses one outside the agent's scope, pointing at `request_connection`.

## Tools bind to the vendor, not the connection

An authored tool is bound to a connection's **vendor slug** (`github`), not to the connection row. That is what lets a revoked connection's tools stay in the toolbox, awaiting reconnection, and ask again once a credential is re-entered.

## Try it

```text
Connect my Linear workspace so you can read issues from it.
```

```text
Which hosts will my Unleashed key be sent to?
```

```text
Propose a connection to Notion, but do not build anything yet.
```
