Share and revoke access
Grant a role on an address or folder, change or revoke a grant, and check who has access and where it comes from.
Address access is granted either selectively, on a single address, or broadly, on an entire folder, with the viewer or contributor role. The subject can be a user or a group, and a folder grant also covers future addresses. This guide shows how to grant, change, and revoke access and how to check who has it. For the underlying model, see Addresses, folders, and access.
Where address access comes from and how it shows up in participants:
Prerequisites
- The Vault's
codeand the id of the address or folder. - A subject: a
userIdor a group id. - An access token (see Authentication).
Access roles:
| Role | What it roughly grants |
|---|---|
viewer | viewing the address, or the folder and its addresses |
contributor | extended permissions (see Addresses, folders, and access for the exact set) |
The canCreateAddress permission isn't part of any role and is granted separately.
Step 1. Grant access to an address
POST /api/v1/vaults/{code}/addresses/{id}/shares issues a grant on a specific address. The subject is polymorphic (subjectType: user|group), and permissions are set by the role.
curl -X POST "[BASE_URL]/api/v1/vaults/acme-otc/addresses/ADDRESS_ID/shares" \
-H "Authorization: Bearer $V3_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "subjectType": "user", "subjectId": "USER_ID", "role": "viewer" }'
await fetch("[BASE_URL]/api/v1/vaults/acme-otc/addresses/ADDRESS_ID/shares", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.V3_TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ subjectType: "user", subjectId: "USER_ID", role: "viewer" }),
});
requests.post(
"[BASE_URL]/api/v1/vaults/acme-otc/addresses/ADDRESS_ID/shares",
headers={"Authorization": f"Bearer {os.environ['V3_TOKEN']}"},
json={"subjectType": "user", "subjectId": "USER_ID", "role": "viewer"},
)
An address grant is idempotent: granting again to the same subject updates the permissions and reactivates a revoked grant, so there's no separate "update" call. For the batch form, use subjects[]. The canCreateAddress permission isn't part of any role and is granted separately. See the API Reference for the exact schema.
Step 2. Grant access to a folder
A folder grant gives permissions on all of the folder's addresses, including ones added later:
curl -X POST "[BASE_URL]/api/v1/vaults/acme-otc/address-folders/FOLDER_ID/grants" \
-H "Authorization: Bearer $V3_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "subjectType": "group", "subjectId": "USER_GROUP_ID", "role": "contributor" }'
await fetch("[BASE_URL]/api/v1/vaults/acme-otc/address-folders/FOLDER_ID/grants", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.V3_TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ subjectType: "group", subjectId: "USER_GROUP_ID", role: "contributor" }),
});
requests.post(
"[BASE_URL]/api/v1/vaults/acme-otc/address-folders/FOLDER_ID/grants",
headers={"Authorization": f"Bearer {os.environ['V3_TOKEN']}"},
json={"subjectType": "group", "subjectId": "USER_GROUP_ID", "role": "contributor"},
)
Step 3. Change or revoke a grant
Which request to use for each action:
| Action | Request |
|---|---|
| grant on an address | POST .../addresses/{id}/shares |
| grant on a folder | POST .../address-folders/{id}/grants |
| change a folder grant | PATCH .../address-folders/{id}/grants/{grantId} |
| revoke a folder grant | DELETE .../address-folders/{id}/grants/{grantId} |
| change an address grant | repeat POST .../shares (idempotent) |
| revoke an address grant | DELETE on the share |
curl -X PATCH "[BASE_URL]/api/v1/vaults/acme-otc/address-folders/FOLDER_ID/grants/GRANT_ID" \
-H "Authorization: Bearer $V3_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "role": "viewer" }'
await fetch("[BASE_URL]/api/v1/vaults/acme-otc/address-folders/FOLDER_ID/grants/GRANT_ID", {
method: "PATCH",
headers: {
Authorization: `Bearer ${process.env.V3_TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ role: "viewer" }),
});
requests.patch(
"[BASE_URL]/api/v1/vaults/acme-otc/address-folders/FOLDER_ID/grants/GRANT_ID",
headers={"Authorization": f"Bearer {os.environ['V3_TOKEN']}"},
json={"role": "viewer"},
)
Revoking a group grant removes access for all of the group's members; a personal grant is revoked individually.
Step 4. Check who has access and where it comes from
curl "[BASE_URL]/api/v1/vaults/acme-otc/addresses/ADDRESS_ID/participants" \
-H "Authorization: Bearer $V3_TOKEN"
const res = await fetch(
"[BASE_URL]/api/v1/vaults/acme-otc/addresses/ADDRESS_ID/participants",
{ headers: { Authorization: `Bearer ${process.env.V3_TOKEN}` } },
);
console.log(await res.json());
requests.get(
"[BASE_URL]/api/v1/vaults/acme-otc/addresses/ADDRESS_ID/participants",
headers={"Authorization": f"Bearer {os.environ['V3_TOKEN']}"},
).json()
participants lists people (the owner is returned separately, and groups are expanded), and the via field shows the source of access and therefore how to remove it:
via | Source | How to remove |
|---|---|---|
direct | personal grant on the address | DELETE the share |
user_group | group grant | remove from the group or revoke the group grant |
| folder | folder grant | change or revoke the folder grant |
Related lists:
| List | Request |
|---|---|
| shared with me (direct only) | GET .../shared-with-me |
| shared by me | GET .../shared-by-me |
| everything accessible to me | GET .../addresses?access=shared |
| address participants | GET .../addresses/{id}/participants |
Common mistakes
| Symptom | Cause |
|---|---|
| grant "duplicated" | a repeated POST /shares doesn't create a second grant; it updates idempotently |
| access wasn't removed | the personal grant was revoked, but access remains via a group or folder; check via |
| no permission to create addresses | canCreateAddress isn't part of any role and is granted separately |
| group revocation affected too many people | DELETE on a group grant removes access for all of its members |
| a future address isn't accessible | the grant was issued on an address, not a folder |
You're done when
POSTon a share or grant has created access with the right role;PATCHchanges a folder grant's role, andDELETErevokes it;participants.viashows the source of access;- revoking through the right source actually removes access.