Appearance
Safety model
An agent that can email documents to people can do harm if it's wrong, misled or compromised. JustDocs is built so that an agent can't put a document in front of anyone without a person agreeing first.
A person approves every send
Anything an agent key asks to send waits for the workspace's owner, or a team's owner or admin. An app that signs in with OAuth is an agent key too:
| The agent calls | What happens |
|---|---|
create_signing_request with send: true | The request is created as a draft. The send waits for approval. |
send_signing_request | The send waits for approval. |
create_intake_request | Nothing is created or emailed until approval. |
create_signing_request with send: false | A draft is created. Nothing is emailed. |
create_template | A template is saved in the workspace, from the agent's text or a library entry. Nothing is emailed, so it needs no approval. In a team, it's shared with the team for use, as a template saved in the app is. |
start_document | A document is created in the workspace. Nothing is emailed. |
void_signing_request | Takes effect at once, without approval. A sent request that isn't complete is cancelled, and recipients who were invited are emailed that it was. |
A template an agent wrote reaches no one until someone sends a document started from it, and every send through an agent key waits for approval, whoever made the template.
The approver sees the title, every address, and the key that asked. Approving sends it in the name of the person who made the key. At that moment the key is checked again: it must not be revoked or expired, its creator must still be an owner or admin, and for an API key the workspace must still be on Teams & Platform. Its recipient domains and daily limit are checked again too. If the send fails, the approval ends failed with the reason.
An approval that nobody decides expires after seven days. JustDocs checks for expired approvals every ten minutes, and again whenever approvals are read, so the approval.decided webhook for it arrives within about ten minutes of the deadline. If someone sends the request from the app instead, the waiting approval expires at once and can no longer be approved.
The agent learns the outcome from get_approval, or your systems from the approval.decided webhook.
Voiding
Voiding is the one action with the send permission that doesn't wait. It can only stop something: a voided request can't be signed, and the only email it causes is the notice to recipients who were already invited. It reaches every request the key's creator could void in the app, which for an owner or admin is any request in the workspace. If an agent shouldn't cancel requests, don't give its key send.
What an agent can never do
- Sign, accept or decline for anyone. There is no such tool.
- See a signing link. Recipients get their private link by email only. No response includes it.
- Reach outside its workspace. A key belongs to one workspace and sees only what its creator can see there.
get_workspacesays which. An id from another workspace is answered as not found, in the same words whether or not it exists. - Outlive its creator's role. If the person who made the key stops being an owner or admin, the key stops working.
- Get a key from a person or another key. Only owners and admins make keys, in the app, or connect an app on JustDocs's own page.
Least privilege
When you make a key, choose only what the agent needs:
| Setting | Limits |
|---|---|
| Permissions | read only, or with documents to create templates and start documents, or with send to ask to send (and to void). Tools outside the key's permissions aren't listed. |
| Recipient domains | The only domains it may send to, including their subdomains. |
| Sends a day | Sends over any 24 hours, approved ones included. |
| Days it works | When the key expires, at most a year. |
Revoke a key from the API & agents page at any time. It stops working at once.
Apps that sign in
An app that signs in with OAuth gets no more than an agent key would.
What it can do:
- Act as an agent key made by the person who approved it. It has the permissions, recipient domains, sends a day and expiry they chose, and every send waits for approval.
- Use only the permissions it asked for and the person kept. A refresh can narrow them, never add one.
- Reach the MCP server only. Its tokens are bound to
https://tryjustdocs.com/mcp, and the REST API refuses them.
What it can't do:
- Sign, see a signing link or approve its own sends. Approvals are made in JustDocs, by a person.
- Borrow someone else's approval. Connections are per person: another admin who connects the same app gets a separate key, acting in their name.
- Keep working after it's disconnected. Disconnect on the API & agents page stops it at once, as does the key expiring or the person stopping being an owner or admin.
- Hold a long-lived secret. Access tokens last an hour. Refresh tokens rotate, and an old one used again ends the sign-in, so a stolen refresh token can't quietly keep working beside the app. JustDocs never gives apps a client secret.
The page where a person connects an app shows:
- the account that's signed in;
- the app's verified domain, or that it's unverified;
- exactly where the sign-in returns, with a warning when that's another domain or a program on the computer.
Only the browser that started a sign-in can see or approve it, and only for 10 minutes. JustDocs never sends anyone back to an app until a signed-in person chooses to connect or cancel.
A trail of everything
- Every request records which key acted, and when. The key's last used time and address, updated at most once a minute, are shown on the API & agents page, so you can spot use from somewhere unexpected.
- Approvals keep who asked, who decided, when, and what happened.
- Webhooks can mirror every send, view, signature and decision into your own systems.
Instructions sent to the agent
On connecting, the server tells the agent how JustDocs works. Every tool works in the key's one workspace. With no suitable template, it can create one. Sends are held for approval. It can never sign for anyone. It should retry with the same idempotency_key. See the exact text. Tool descriptions are fixed in the server, never taken from documents or user input. That leaves less room for prompt injection through a template or an answer.
Annotations
Each tool declares all three MCP annotations explicitly: readOnlyHint for the eight reading tools, and openWorldHint with destructiveHint for the tools that reach other people — the sending tools, whose email can't be unsent once a person approves it, and void_signing_request. Clients use these to ask you before running a tool. Many clients confirm every write. JustDocs's approvals apply whatever the client does.