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

# Tool Sharing and Identity

> Who a tool acts as when you share an agent or workflow — and how to share a connection along with it

When you share an agent that uses Salesforce, Gmail, or any other connected app, a question follows immediately: **whose account does it use?**

The short answer: **by default, the person running the agent uses their own connection.** Sharing an agent does not share its credentials. But you can deliberately share your connection alongside it, so everyone runs as *you*.

This page explains both models, how to set them up, and when each is the right choice.

## The core rule

Pinkfish separates three things that are easy to conflate:

| Thing              | What it is                                           | Who owns it             |
| ------------------ | ---------------------------------------------------- | ----------------------- |
| **The agent**      | Instructions, tool selections, resources             | The builder             |
| **The tool**       | An MCP server exposing actions like "Run SOQL query" | The platform / your org |
| **The connection** | The authenticated session with the third-party app   | **An individual user**  |

Credentials always live on the **connection**, never on the agent. An agent stores at most a *reference* to a connection — never a token, key, or password. When someone runs the agent, Pinkfish resolves that reference against **the connections the runner can access**.

<Note>
  This is why sharing an agent with your org doesn't leak your Salesforce login. It also means a teammate who opens your shared agent will hit a "connect your account" prompt unless you take the extra step described below.
</Note>

## Model 1: Per-user identity (the default)

Each person who runs the agent connects their own account. The agent acts as *them*.

<Steps>
  <Step title="Build the agent and add tools">
    Under the agent's **Tools** tab, select the connection-backed servers you need (e.g. Salesforce). Leave the connection selector on **Default (any)**.
  </Step>

  <Step title="Share the agent">
    Share it with individuals or the whole org as normal.
  </Step>

  <Step title="Each user connects">
    The first time a teammate runs a tool that needs Salesforce, Pinkfish uses *their* Salesforce connection. If they have exactly one, it's selected automatically. If they have several, they're asked to pick. If they have none, they're prompted to connect one.
  </Step>
</Steps>

**Use this when** the third-party app already enforces the right per-user permissions, and you want each person's actions attributed to them. A support agent that reads Salesforce cases should generally see only the cases that user is allowed to see.

## Model 2: Shared identity (pin the builder's connection)

Everyone who runs the agent uses **one** connection — yours, or a dedicated service account's. Nobody else needs to connect anything.

This requires **two separate actions**. Doing only one of them is the most common mistake on this page.

<Steps>
  <Step title="Share the connection">
    Go to **Tools → Connections**, find the connection, open the **⋯** menu and choose **Share**. Grant access to specific users or to your entire organization.

    Sharing requires **Manage** permission on the connection. Recipients need at least **Run** to use it in an agent or workflow. See [Connections → Sharing and Permissions](/tools/connections#sharing-and-permissions).
  </Step>

  <Step title="Pin the connection on the agent">
    In the agent editor, open the **Tools** tab and find the server. Use the **Connection** selector next to it to pick the specific shared connection instead of **Default (any)**.
  </Step>
</Steps>

Now, when a teammate runs the agent, the pinned connection is used and no prompt appears. Their tool calls hit Salesforce as your user.

<Warning>
  **Pinning without sharing breaks the agent for everyone else — it does not quietly fall back.**

  If a runner can't access the pinned connection, Pinkfish **does not** substitute their own. It refuses the tool call with:

  > The connection pinned to "*{server}*" is no longer available. Ask your agent builder to update the pinned connection.

  This is deliberate: silently swapping in a different account would run the agent under an identity nobody chose. The same error appears if the pinned connection is later deleted, or if it's pinned to a connection for a different app.

  So if teammates report that error, the fix is step 1 — share the connection — not to unpin it.
</Warning>

<Note>
  A user who explicitly picks a connection in the chat (when prompted) overrides the pin for that conversation. That's an explicit choice, not a silent fallback.
</Note>

## What happens when a connection is missing

The behavior differs by surface, and the difference is intentional.

| Surface                                                            | Behavior when the runner lacks the connection                                                                                                                                |
| ------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Agents** (chat, Slack, Teams)                                    | Resolved *at the moment the tool is called*. The run proceeds until then, and the user gets a **Connection Required** prompt or a connection picker.                         |
| **Guided workflows**                                               | Checked *before the run starts*. The run is blocked with an error naming the missing connections: "Ask the workflow owner to share them, or select your own before running." |
| **Triggered runs** (schedule, email, webhook, API key, app events) | Not applicable — a triggered run never uses the caller's connections. It always runs as the trigger's owner. See below.                                                      |

Agents are conversational, so they can ask mid-run. Workflows may take a long time and cause side effects, so they fail fast instead of dying halfway through.

## Triggers always run as their owner

This is the single most important thing to understand before you hand out a webhook URL or an API key.

When you create a trigger — a schedule, an inbound email address, an API/webhook endpoint, or an app-event subscription — Pinkfish records **your** identity on it. Every time that trigger fires, the run executes with **your connections**, no matter who or what caused it to fire.

The inbound API key authenticates *that the call is allowed to fire the trigger*. It does not establish who the caller is, and it never causes the run to use the caller's own connections. There is no per-caller identity on a triggered run.

<Warning>
  **Distributing a trigger URL or API key delegates your credentials.**

  Anyone holding the key can invoke that workflow, and it will run with your Salesforce, Gmail, or database connections. Treat a trigger URL exactly as you would treat the credentials it can reach.

  The key is bound to one trigger, so a holder cannot enumerate your other workflows or connections with it. But *within* that workflow, your credentials are fully in play.
</Warning>

### A workflow trigger is narrow: it runs the workflow as written

This is the reassuring part, and it's worth being precise about.

Holding a workflow's trigger URL does **not** give someone general access to your connection. They cannot read its credentials, list your other connections, or use it outside that workflow. They supply the workflow's declared inputs; they cannot add, remove, or reorder its steps. The step list comes from the saved workflow on the server, never from the request.

So the operations reachable through a distributed trigger URL are exactly the operations the builder wrote into that workflow. A workflow that only creates a Salesforce lead exposes only lead creation — not a general Salesforce credential.

Two things can widen that, both worth designing against:

<Warning>
  **1. Unsafe inputs.** The containment above is a property of *your workflow's code*, not something the platform enforces. If a step interpolates a caller-supplied input into a request path, a query string, a request body, or a SOQL/SQL string, a caller who controls that input can steer the call — with your credentials behind it.

  Treat trigger inputs as untrusted, exactly as you would query parameters on a public HTTP endpoint. Prefer structured parameters over string-interpolating an input into a URL path or a query.
</Warning>

<Warning>
  **2. Agent API channels are not narrow.** A workflow trigger accepts declared inputs. An **agent's** API channel accepts a free-text message, which an LLM then acts on by choosing tools at runtime — against your connections, and including the code-execution tool every agent gets automatically.

  Whoever holds that key is effectively chatting with your agent. The reachable surface is the agent's whole tool set, not one coded procedure. Scope an externally-exposed agent's tools tightly, and prefer requiring a verified caller identity (below).
</Warning>

### Verified callers do not change the identity

An API trigger can require the caller to present a signed identity token from an identity provider you trust. The workflow then receives their verified claims as a `_verified` input, so it knows *who asked*.

That identity is **data, not an execution identity**. The run still uses the trigger owner's connections. See [Verified Inputs](/triggers/verified-inputs).

The one place a verified caller identity *does* become an execution identity is A2A end-user connections, below.

## Identity reference: what does each surface run as?

Every run has a single **run-as identity**. Connections resolve against that identity — its own connections, plus anything shared with it directly or through its organization. Everything on this page is a consequence of that one rule.

Here is the complete picture.

| Surface                                                        | Runs as                                      | Consequence                                                                                                                                   |
| -------------------------------------------------------------- | -------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
| **Web app** — you run an agent or workflow                     | You                                          | Your connections.                                                                                                                             |
| **Web app** — you run something shared with you                | You                                          | Your connections, not the owner's. A guided workflow blocks before starting if you lack one it needs; an agent asks when it reaches the tool. |
| **Agent tool with a pinned connection**                        | You, but the tool uses the pinned connection | Requires that the connection was shared with you. If not, the tool call fails rather than substituting your own.                              |
| **Any trigger** — schedule, email, API key, webhook, app event | The **trigger's creator**                    | The creator's connections, every time, no matter who or what fired it.                                                                        |
| **Agent API channel**                                          | The **agent's owner**                        | The caller sends free text; the agent picks tools using the owner's connections.                                                              |
| **Slack / Teams — shared bot, direct message**                 | **The person messaging**                     | Matched to their Pinkfish account by their Slack/Teams email. They use their own connections.                                                 |
| **Slack / Teams — shared bot, channel thread**                 | **Whoever started the thread**               | Later repliers in that thread run as the initiator. See the warning below.                                                                    |
| **Slack / Teams — dedicated bot**                              | The **agent's owner**                        | Every participant runs as the owner. Participants need no Pinkfish account.                                                                   |
| **A2A with end-user connections**                              | **The verified external caller**             | Each caller uses their own connections. Rejected outright if no verified identity is presented.                                               |

### Slack and Microsoft Teams in detail

Which identity a chat runs as depends on how the bot was installed — this is the least obvious part of the model.

**Shared bot.** Pinkfish matches the sender's Slack or Teams profile email to their Pinkfish account. In a **direct message**, that is simply the person typing, so they use their own connections. This is what most people expect.

<Warning>
  **In a shared channel, a thread runs as whoever started it.**

  Pinkfish binds an identity to the *thread* on its first message, not to each message. If Alice starts a thread with the agent and Bob replies in that same thread, **Bob's message executes under Alice's account and Alice's connections.**

  Bob does not need access to Alice's connections, and he is not asked to connect his own. Treat an agent in a shared channel as running with the connections of whoever speaks to it first.

  (In Teams the binding is per *conversation* rather than per thread, so it is even broader.)
</Warning>

**Dedicated bot** — the "connect one agent" install with your own Slack or Teams app. Here the identity is fixed to the **agent owner** for every participant, and the sender's email is used only to attribute the message in Monitor. End users do not need a Pinkfish account at all. This is a deliberate design: a dedicated bot is meant to serve people who aren't Pinkfish users.

### The exception: external end users over A2A

An agent exposed over the A2A protocol can be configured to require **end-user connections**. In that mode each external caller must present a verified identity token from a trusted identity provider, and connections resolve against that caller's own account — never the builder's. Calls without a verified end-user identity are rejected rather than falling back to the builder.

This is the only surface where an externally-invoked run executes as the invoker rather than the owner.

## Templates and copies

Publishing an agent to the template gallery **strips all connection information**. The template carries only the name, description, instructions, and the *names* of the tools it used.

When someone clones a template, they get the tool selections but must supply their own connections. A pinned connection reference does not grant the cloner any access to it — access is checked against the runner every time, so a copied reference is inert.

<Note>
  The same holds for duplicating an agent or workflow into another organization. Connections never cross an org boundary.
</Note>

## The security tradeoff

Sharing a connection org-wide is a real delegation of authority. Be deliberate about it.

When ten people run an agent pinned to your Salesforce connection:

* **Their data access becomes your data access.** Row-level security, field-level security, and sharing rules in Salesforce all resolve against *your* user. If you're an ops admin who can see every opportunity in the company, so can everyone running the agent — through the agent, regardless of their own Salesforce permissions.
* **Attribution collapses.** Salesforce's audit log will attribute every query and every write to your user, not to the person who actually asked for it. Pinkfish's own run history still records who ran the agent.
* **Revocation is coarse.** Unsharing the connection immediately breaks the agent for everyone.

<Warning>
  Do not pin a highly-privileged personal account to an org-wide agent as a convenience. If you want a shared identity, create a **dedicated service account** in the upstream app, scope it to exactly the permissions the agent needs, connect it in Pinkfish, and share *that* connection.
</Warning>

### Choosing between the two models

<CardGroup cols={2}>
  <Card title="Prefer per-user identity" icon="users">
    The upstream app enforces meaningful per-user permissions. You need accurate audit trails. Users can reasonably be asked to connect their own accounts.
  </Card>

  <Card title="Prefer a shared service identity" icon="robot">
    The agent needs uniform access regardless of who runs it. Onboarding friction matters. The upstream app has no per-user permission model worth preserving (a shared inbox, an internal API, a reporting warehouse).
  </Card>
</CardGroup>

## Related

* [Connections](/tools/connections) — connecting apps, permissions, custom integrations
* [Sharing](/organization/sharing) — sharing workflows and connections across your org
* [Agents → Tools tab](/agents/tools) — selecting which tools an agent can call
* [Triggers](/agentic-editor/triggers) — creating schedule, API, email, and app triggers
* [API Reference → Authentication](/api-reference/introduction) — trigger API keys and webhook URLs
