Sharing
Manage query access control with team and user-level sharing.
Query Sharing Overview
Queries support granular sharing with:
- Individual Users - Share with specific users
- Teams - Share with entire teams
- Access Levels - Control read/write permissions via numeric levels
- Inheritance - Team-owned queries inherit team permissions
GET /api/queries/{id}/shares
Get all shares for a query.
Authentication: Required
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
id | string | Query ID (UUID) or natural ID |
Response:
{
"_links": {
"self": { "href": "/api/queries/{id}/shares" }
},
"_embedded": {
"inf:share": [
{
"queryId": "550e8400-e29b-41d4-a716-446655440000",
"principalId": "john.doe",
"accessLevel": 2,
"createdAt": "2024-01-20T10:00:00Z",
"updatedAt": "2024-01-20T10:00:00Z"
},
{
"queryId": "550e8400-e29b-41d4-a716-446655440000",
"principalId": "team:finance",
"accessLevel": 1,
"createdAt": "2024-01-15T14:30:00Z",
"updatedAt": "2024-01-15T14:30:00Z"
},
{
"queryId": "550e8400-e29b-41d4-a716-446655440000",
"principalId": "jane.smith",
"accessLevel": 3,
"createdAt": "2024-02-01T09:15:00Z",
"updatedAt": "2024-02-01T09:15:00Z"
}
]
},
"start": 0,
"count": 3,
"total": 3
}
Share Properties:
| Property | Type | Description |
|---|---|---|
queryId | UUID | Query identifier |
principalId | string | User ID or team ID (format: team:{slug}) |
accessLevel | integer | Permission level (1-10) |
createdAt | datetime | When share was created |
updatedAt | datetime | When share was last modified |
Access Levels:
| Level | Description | Permissions |
|---|---|---|
| 1 | Read | View query definition and results |
| 2 | Execute | Read + run query |
| 3 | Edit | Execute + modify query |
| 5 | Share | Edit + manage shares |
| 10 | Full | All permissions |
- Use level 1 for viewers who only need to see query structure
- Use level 2 for users who need to run queries
- Use level 3 for collaborators who can edit
- Use level 5 for admins who manage access
GET /api/queries/{id}/shares/{principalId}
Get a specific share for a query and principal.
Authentication: Required
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
id | string | Query ID (UUID) or natural ID |
principalId | string | User ID or team ID (e.g., team:finance) |
Response:
{
"queryId": "550e8400-e29b-41d4-a716-446655440000",
"principalId": "john.doe",
"accessLevel": 2,
"createdAt": "2024-01-20T10:00:00Z",
"updatedAt": "2024-01-20T10:00:00Z"
}
Returns 404 if no share exists for the principal.
PUT /api/queries/{id}/shares/{principalId}
Create or update a share for a query.
Authentication: Required
Permission: query:share
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
id | string | Query ID (UUID) or natural ID |
principalId | string | User ID or team ID |
Request Body:
{
"accessLevel": 2
}
Validation:
| Field | Type | Required | Description |
|---|---|---|---|
accessLevel | integer | Yes | Access level (1-10, must be > 0) |
Response:
Returns the created or updated share with 200 OK status.
{
"queryId": "550e8400-e29b-41d4-a716-446655440000",
"principalId": "john.doe",
"accessLevel": 2,
"createdAt": "2024-02-09T11:00:00Z",
"updatedAt": "2024-02-09T11:00:00Z"
}
Activity Tracking:
Creating or updating a share triggers a queryShared activity entry for audit logging.
Access level must be an integer between 1 and 10. To remove a share, use DELETE instead of setting accessLevel: 0.
DELETE /api/queries/{id}/shares/{principalId}
Remove a share from a query.
Authentication: Required
Permission: query:share
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
id | string | Query ID (UUID) or natural ID |
principalId | string | User ID or team ID |
Response:
Returns 204 No Content on success, or 404 if share doesn't exist.
Deleting a share removes all access for that principal. To change access level, use PUT instead.
Sharing Best Practices
Team Ownership vs Individual Shares
| Scenario | Approach |
|---|---|
| Query owned by team | Team members inherit access via team role |
| Query owned by user | Use individual shares or transfer to team |
| Cross-team collaboration | Share with other teams using team ID |
| External consultants | Share with individual user accounts |
Access Level Strategy
// Read-only access for viewers
PUT /api/queries/my-query/shares/viewer.user
{ "accessLevel": 1 }
// Execute access for analysts
PUT /api/queries/my-query/shares/analyst.user
{ "accessLevel": 2 }
// Edit access for collaborators
PUT /api/queries/my-query/shares/collaborator.user
{ "accessLevel": 3 }
// Full access for co-owners
PUT /api/queries/my-query/shares/admin.user
{ "accessLevel": 5 }
Bulk Sharing
// Share with multiple users at once
const users = ['alice', 'bob', 'charlie'];
const accessLevel = 2;
for (const userId of users) {
await PUT(`/api/queries/my-query/shares/${userId}`, {
accessLevel
});
}
Share Management Workflow
-
Audit Current Shares
GET /api/queries/my-query/shares -
Add New Collaborators
PUT /api/queries/my-query/shares/new.user
{ "accessLevel": 3 } -
Update Access Levels
PUT /api/queries/my-query/shares/existing.user
{ "accessLevel": 2 } -
Remove Access
DELETE /api/queries/my-query/shares/former.user
Security Considerations
- Minimum Privilege - Grant lowest access level needed
- Regular Audits - Review shares periodically
- Team Ownership - Use teams for department-wide queries
- Share Permission - Limit who can manage shares (level 5+)
- Activity Monitoring - Track share changes via activity log
Common Patterns
Share with entire department:
PUT /api/queries/sales-query/shares/team:sales
{
"accessLevel": 2
}
Grant edit access to collaborator:
PUT /api/queries/sales-query/shares/john.doe
{
"accessLevel": 3
}
Promote user to co-owner:
PUT /api/queries/sales-query/shares/jane.smith
{
"accessLevel": 5
}
Revoke all access:
DELETE /api/queries/sales-query/shares/former.employee
Permissions vs Shares
Shares Control Access
Shares determine who can access a query and at what level:
- Created via
/sharesendpoints - Stored in
query_sharetable - Evaluated during permission checks
Permissions Control Actions
Permissions determine what actions can be performed:
- Evaluated via permission drivers
- Based on team roles, ownership, and shares
- Returned in
permissionsobject on query
Example:
// User has share with accessLevel: 3
GET /api/queries/my-query
{
"id": "my-query",
"ownerId": "team:analytics",
"permissions": {
"write": true, // Can edit (accessLevel >= 3)
"run": true, // Can execute (accessLevel >= 2)
"share": false, // Cannot manage shares (needs accessLevel >= 5)
"delete": true // Can delete (delegates to write)
}
}
Effective Permissions
Final permissions are the maximum of:
- Ownership - Owner has all permissions
- Team Role - Team members get role-based permissions
- Shares - Explicit shares grant additional access
- Superuser - Superusers always have full access
Team Admin > Owner > Share Level 10 > Share Level 5 > Share Level 3 > Share Level 2 > Share Level 1