Sharing & Permissions
Manage dataset access control with user/team sharing, access levels, and field restrictions.
GET /api/datasets/{id}/shares
Get all shares for a dataset with access levels, filter IDs, and field restrictions.
Authentication: Required
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
id | string | Dataset ID or slug |
Response:
{
"_links": {
"self": { "href": "/api/datasets/{id}/shares" }
},
"_embedded": {
"inf:share": [
{
"datasetId": "sales-2024",
"principalId": "team:marketing",
"principal": {
"id": "team:marketing",
"name": "Marketing Team",
"type": "team"
},
"accessLevel": 2,
"datasetFilterId": "filter-high-value",
"restrictFields": false,
"visibleFields": null,
"createdAt": "2024-01-15T10:00:00Z",
"updatedAt": "2024-02-08T15:00:00Z"
},
{
"datasetId": "sales-2024",
"principalId": "user:analyst1",
"principal": {
"id": "user:analyst1",
"name": "Analyst User",
"type": "user",
"email": "analyst@example.com"
},
"accessLevel": 1,
"datasetFilterId": null,
"restrictFields": true,
"visibleFields": ["order_id", "customer_name", "amount", "order_date"],
"createdAt": "2024-01-20T14:00:00Z",
"updatedAt": "2024-01-20T14:00:00Z"
}
]
},
"start": 0,
"count": 2,
"total": 2
}
Share Properties:
| Property | Type | Description |
|---|---|---|
principalId | string | User or team ID |
principal | object | User/team details |
accessLevel | integer | Access level (0-3) |
datasetFilterId | string | Applied filter ID (null for no filter) |
restrictFields | boolean | Enable field-level restrictions |
visibleFields | array | List of visible fields (when restrictFields=true) |
Access Levels:
| Level | Name | Permissions |
|---|---|---|
| 0 | None | No access |
| 1 | View | Read data and structure |
| 2 | Edit | View + modify data and fields |
| 3 | Admin | Edit + manage sharing and ownership |
GET /api/datasets/{id}/shares/{principalId}
Get a single share for a specific user or team.
Authentication: Required
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
id | string | Dataset ID or slug |
principalId | string | User or team ID |
Response:
{
"datasetId": "sales-2024",
"principalId": "team:marketing",
"principal": {
"id": "team:marketing",
"name": "Marketing Team",
"type": "team"
},
"accessLevel": 2,
"datasetFilterId": "filter-high-value",
"restrictFields": false,
"visibleFields": null,
"createdAt": "2024-01-15T10:00:00Z",
"updatedAt": "2024-02-08T15:00:00Z"
}
PUT /api/datasets/{id}/shares/{principalId}
Create or update a share for a user or team.
Authentication: Required
Permission: dataset:share
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
id | string | Dataset ID or slug |
principalId | string | User or team ID |
Request Body:
| Field | Type | Required | Description |
|---|---|---|---|
accessLevel | integer | Yes | Access level (1-3, must be > 0) |
datasetFilterId | string | No | Filter to apply for this share |
restrictFields | boolean | No | Enable field restrictions (default: false) |
visibleFields | array | No | List of visible fields (when restrictFields=true) |
Example Request (basic share):
{
"accessLevel": 2
}
Example Request (with filter):
{
"accessLevel": 1,
"datasetFilterId": "filter-west-region"
}
Example Request (with field restrictions):
{
"accessLevel": 1,
"restrictFields": true,
"visibleFields": [
"order_id",
"customer_name",
"amount",
"order_date"
]
}
Response:
Returns the created or updated share object.
Behavior:
- Creates new share if none exists for principal
- Updates existing share if already exists
accessLevelmust be greater than 0- Field restrictions require dataset to have field-level security enabled
PUT creates a new share or updates an existing one for the same principal. There's no separate POST endpoint for share creation.
DELETE /api/datasets/{id}/shares/{principalId}
Revoke access by deleting a share.
Authentication: Required
Permission: dataset:share
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
id | string | Dataset ID or slug |
principalId | string | User or team ID |
Response:
204 No Content
Behavior:
- Removes share entry
- User/team loses all access to dataset
- Does not affect owner access
GET /api/datasets/{id}/permissions
Get available permissions for the dataset for the current user.
Authentication: Required
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
id | string | Dataset ID or slug |
Response:
{
"read": true,
"write": true,
"refresh": true,
"copy": true,
"share": true,
"edit": true,
"delete": true,
"addVisual": true,
"deleteVisual": true,
"assignTags": true,
"changeOwner": false
}
Permission Descriptions:
| Permission | Description |
|---|---|
read | View dataset and data |
write | Modify dataset, fields, data |
refresh | Execute refresh from datasource |
copy | Create copies and snapshots |
share | Manage sharing and access |
edit | Modify dataset properties |
delete | Delete dataset |
addVisual | Create/modify visuals |
deleteVisual | Remove visuals |
assignTags | Add/remove tags |
changeOwner | Transfer ownership |
Use Case:
Check permissions before showing UI controls or attempting operations. Client-side permission checks prevent unnecessary API calls.
Sharing Examples
Share with Team (Edit Access)
await PUT('/api/datasets/sales-2024/shares/team:marketing', {
accessLevel: 2 // Edit access
});
Share with User (View Only + Filter)
await PUT('/api/datasets/sales-2024/shares/user:analyst1', {
accessLevel: 1,
datasetFilterId: 'filter-west-region' // User only sees West region data
});
Share with Field Restrictions
// First, enable field-level security on dataset
await POST('/api/dataset-field-report-access', {
'sales-2024': true
});
// Then create share with field restrictions
await PUT('/api/datasets/sales-2024/shares/user:contractor', {
accessLevel: 1,
restrictFields: true,
visibleFields: [
'order_id',
'order_date',
'amount'
// Sensitive fields like customer_name, internal_notes not included
]
});
Share with Multiple Teams
const teams = ['team:marketing', 'team:sales', 'team:operations'];
for (const teamId of teams) {
await PUT(`/api/datasets/sales-2024/shares/${teamId}`, {
accessLevel: 1 // View access for all teams
});
}
Revoke Access
await DELETE('/api/datasets/sales-2024/shares/user:former-employee');
Access Control Patterns
Hierarchical Access
Owner > Admin Share (level 3) > Edit Share (level 2) > View Share (level 1)
// Owner has full control
// Team admins get level 3
await PUT('/api/datasets/sales-2024/shares/team:admins', {
accessLevel: 3
});
// Analysts get edit access
await PUT('/api/datasets/sales-2024/shares/team:analysts', {
accessLevel: 2
});
// Viewers get read-only
await PUT('/api/datasets/sales-2024/shares/team:viewers', {
accessLevel: 1
});
Regional Data Segmentation
Use filters to segment data by region:
// West region team sees only West data
await PUT('/api/datasets/sales-2024/shares/team:west-sales', {
accessLevel: 2,
datasetFilterId: 'filter-west-region'
});
// East region team sees only East data
await PUT('/api/datasets/sales-2024/shares/team:east-sales', {
accessLevel: 2,
datasetFilterId: 'filter-east-region'
});
Sensitive Data Protection
Restrict fields containing PII or confidential information:
await PUT('/api/datasets/customer-data/shares/team:external-contractors', {
accessLevel: 1,
restrictFields: true,
visibleFields: [
'customer_id', // ID is OK
'region', // Aggregatable field OK
'order_count', // Summary field OK
// 'customer_name', // Excluded - PII
// 'email', // Excluded - PII
// 'phone', // Excluded - PII
// 'credit_card' // Excluded - sensitive
]
});
Best Practices
Permission Design
- Principle of least privilege - Grant minimum access needed
- Use teams - Share with teams rather than individual users
- Document access levels - Maintain record of who has access and why
- Regular audits - Review shares periodically
- Revoke promptly - Remove access when no longer needed
Filter-Based Sharing
- Regional segmentation - Separate data by geography
- Departmental views - Each dept sees relevant data
- Time-based access - Limit to specific date ranges
- Status filtering - Show only active/relevant records
- Compliance - Enforce data residency rules
Field-Level Security
- PII protection - Hide sensitive personal information
- Financial data - Restrict salary, revenue details
- Internal fields - Hide audit trails, internal notes
- Calculated fields - Consider visibility of derived data
- Test thoroughly - Verify field restrictions work as expected
Performance
- Index filter fields - For fast filtered data access
- Limit field restrictions - Too many fields impact performance
- Cache permissions - Client-side permission caching
- Batch share updates - Reduce API calls when sharing with multiple principals
- Monitor query performance - Filters can slow complex queries
Security
- Validate principals - Ensure users/teams exist before sharing
- Check share permissions - Only authorized users can manage shares
- Audit share changes - Log all share modifications
- Prevent privilege escalation - Users can't grant higher access than they have
- Test filters - Ensure filters don't leak data
When using filter-based sharing, ensure the filter completely restricts access. Users can modify queries, so rely on server-side filter enforcement, not client-side filtering.
Prefer team-based sharing over individual user shares. Teams are easier to manage and automatically include new team members.