RecipesRoles rules
Role Management
Creating a Role
const createRoleResult = await broadcastRequest({
action: 'add',
resource: '/roles',
details: {
rid: uuidv4(),
name: 'custom-role',
description: 'Custom role for specific operations',
},
})
const roleId = createRoleResult.details.ridAdding Rules to a Role
// Add multiple rules to a role
const addRulesResult = await broadcastRequest({
action: 'edit',
resource: `/roles/${roleId}/rules/add`,
details: {
rules: [ruleId1, ruleId2, ruleId3],
},
})Removing Rules from a Role
const removeRulesResult = await broadcastRequest({
action: 'edit',
resource: `/roles/${roleId}/rules/remove`,
details: {
rules: [ruleId1],
},
})Listing Roles
const rolesResult = await broadcastRequest({
action: 'get',
resource: '/roles',
details: {
filters: {
name: 'admin', // Optional: filter by name
},
},
})
const roles = rolesResult.detailsGetting Role Details
const roleDetails = await broadcastRequest({
action: 'get',
resource: `/roles/${roleId}`,
details: {},
})
console.log('Role:', roleDetails.details.name)
console.log('Rules:', roleDetails.details.rules)User Role Assignment
Assigning a User to a Role
const assignResult = await broadcastRequest({
action: 'edit',
resource: `/roles/${roleId}/users/add`,
details: {
users: [userId1, userId2],
},
})Removing a User from a Role
const removeResult = await broadcastRequest({
action: 'edit',
resource: `/roles/${roleId}/users/remove`,
details: {
users: [userId1],
},
})Creating User with Roles
// Create user and assign roles in one operation
const userResult = await broadcastRequest({
action: 'add',
resource: '/users',
details: {
uid: uuidv4(),
email: 'user@example.com',
first_name: 'John',
last_name: 'Doe',
ecdsa_pubkey: userKeys.ecdsa.publicKeyHex,
rsa_pubkey: userKeys.rsa.publicKeyPem,
type: 'api',
},
})
// Then assign to role
await broadcastRequest({
action: 'edit',
resource: `/roles/${roleId}/users/add`,
details: {
users: [userResult.details.uid],
},
})Permission Examples by Role
Super Admin
Full access to everything:
const superAdminPermissions = {
roleIdentifier: 'super-admin',
permissions: [
{
permissionIdentifier: 'p1',
description: 'View Everything & Edit everything',
rules: [{ resource: '*', action: '*' }],
},
],
}Workspace Owner with Approval Filter
Workspace owners can approve proposals, but only for workspace-level resources:
const workspaceOwnerPermissions = {
roleIdentifier: 'workspace-owner',
permissions: [
{
permissionIdentifier: 'p1',
description: 'View workspace resources',
rules: [
{ resource: '/users', action: 'list' },
{ resource: '/users', action: 'get' },
{ resource: '/signers', action: 'list' },
{ resource: '/signers', action: 'get' },
{ resource: '/wallets', action: 'list' },
{ resource: '/wallets', action: 'get' },
{ resource: '/policies', action: 'list' },
{ resource: '/policies', action: 'get' },
{ resource: '/roles', action: 'list' },
{ resource: '/roles', action: 'get' },
{ resource: '/rules', action: 'list' },
{ resource: '/rules', action: 'get' },
{ resource: '/groups', action: 'list' },
{ resource: '/groups', action: 'get' },
{ resource: '/recipients', action: 'list' },
{ resource: '/recipients', action: 'get' },
{ resource: '/recipient-groups', action: 'list' },
{ resource: '/recipient-groups', action: 'get' },
],
},
{
permissionIdentifier: 'p2',
description: 'Approve workspace proposals',
rules: [
{
resource: '/proposals',
action: 'approve',
// Filter: only proposals affecting workspace resources
filter: `proposal.resource IN ['/users', '/signers', '/roles', '/policies', '/wallets', '/groups', '/recipients', '/recipient-groups', '/assets']`,
},
],
},
],
}Workspace Maintainer
Manage workspace resources:
const workspaceMaintainerPermissions = {
roleIdentifier: 'workspace-maintainer',
permissions: [
{
permissionIdentifier: 'p1',
description: 'View workspace resources',
rules: [
{ resource: '/users', action: 'list' },
{ resource: '/users', action: 'get' },
{ resource: '/signers', action: 'list' },
{ resource: '/signers', action: 'get' },
{ resource: '/wallets', action: 'list' },
{ resource: '/wallets', action: 'get' },
{ resource: '/policies', action: 'list' },
{ resource: '/policies', action: 'get' },
{ resource: '/roles', action: 'list' },
{ resource: '/roles', action: 'get' },
{ resource: '/rules', action: 'list' },
{ resource: '/rules', action: 'get' },
{ resource: '/groups', action: 'list' },
{ resource: '/groups', action: 'get' },
{ resource: '/recipients', action: 'list' },
{ resource: '/recipients', action: 'get' },
{ resource: '/recipient-groups', action: 'list' },
{ resource: '/recipient-groups', action: 'get' },
{ resource: '/assets', action: 'list' },
{ resource: '/assets', action: 'get' },
],
},
{
permissionIdentifier: 'p2',
description: 'Propose changes to workspace resources',
rules: [
// Users
{ resource: '/users', action: 'invite' },
{ resource: '/users', action: 'create' },
{ resource: '/users', action: 'edit' },
{ resource: '/users', action: 'delete' },
// Rules
{ resource: '/rules', action: 'create' },
// Roles
{ resource: '/roles', action: 'create' },
{ resource: '/roles', action: 'addRules' },
{ resource: '/roles', action: 'removeRules' },
{ resource: '/roles', action: 'addUsers' },
{ resource: '/roles', action: 'removeUsers' },
{ resource: '/roles', action: 'delete' },
// Groups
{ resource: '/groups', action: 'create' },
{ resource: '/groups', action: 'edit' },
{ resource: '/groups', action: 'delete' },
{ resource: '/groups', action: 'addUsers' },
{ resource: '/groups', action: 'removeUsers' },
// Recipients
{ resource: '/recipients', action: 'create' },
{ resource: '/recipients', action: 'edit' },
{ resource: '/recipients', action: 'delete' },
// Recipient Groups
{ resource: '/recipient-groups', action: 'create' },
{ resource: '/recipient-groups', action: 'edit' },
{ resource: '/recipient-groups', action: 'delete' },
{ resource: '/recipient-groups', action: 'addRecipients' },
{ resource: '/recipient-groups', action: 'removeRecipients' },
// Assets
{ resource: '/assets', action: 'edit' },
// Signers
{ resource: '/signers', action: 'create' },
{ resource: '/signers', action: 'edit' },
{ resource: '/signers', action: 'delete' },
// Wallets
{ resource: '/wallets', action: 'create' },
{ resource: '/wallets', action: 'edit' },
{ resource: '/wallets', action: 'delete' },
// Policies
{ resource: '/policies', action: 'create' },
{ resource: '/policies', action: 'edit' },
{ resource: '/policies', action: 'delete' },
],
},
],
}Wallet Maintainer (Per-Wallet Access)
Dynamic rules based on assigned wallets:
function getWalletMaintainerRules(walletId: string) {
return {
roleIdentifier: 'wallet-maintainer',
permissions: [
{
permissionIdentifier: 'p1',
description: 'View wallet resources',
rules: [
{ resource: `/wallets/${walletId}`, action: 'get' },
{ resource: `/wallets/${walletId}/balances`, action: 'get' },
{ resource: `/wallets/${walletId}/addresses`, action: 'get' },
{ resource: `/wallets/${walletId}/addresses`, action: 'list' },
{ resource: `/wallets/${walletId}/transactions`, action: 'get' },
{ resource: `/wallets/${walletId}/transactions`, action: 'list' },
{ resource: `/wallets/${walletId}/spend-requests`, action: 'list' },
{ resource: `/wallets/${walletId}/spend-requests`, action: 'get' },
],
},
{
permissionIdentifier: 'p2',
description: 'Create spend requests',
rules: [{ resource: `/wallets/${walletId}/spend-requests`, action: 'add' }],
},
{
permissionIdentifier: 'p3',
description: 'Review and approve proposals',
rules: [
{
resource: '/proposals',
action: 'review',
filter: `proposal.wallet_id == '${walletId}'`,
},
{
resource: '/proposals',
action: 'approve',
filter: `proposal.wallet_id == '${walletId}'`,
},
],
},
{
permissionIdentifier: 'p4',
description: 'Manage wallet settings',
rules: [
{ resource: `/wallets/${walletId}`, action: 'edit' },
{ resource: `/wallets/${walletId}/policies`, action: 'create' },
{ resource: `/wallets/${walletId}/policies`, action: 'edit' },
{ resource: `/wallets/${walletId}/policies`, action: 'delete' },
],
},
],
}
}Standard Wallet User (Per-Wallet Access)
function getStandardWalletUserRules(walletId: string) {
return {
roleIdentifier: 'standard-wallet-user',
permissions: [
{
permissionIdentifier: 'p1',
description: 'View wallet resources',
rules: [
{ resource: `/wallets/${walletId}`, action: 'get' },
{ resource: `/wallets/${walletId}/balances`, action: 'get' },
{ resource: `/wallets/${walletId}/addresses`, action: 'get' },
{ resource: `/wallets/${walletId}/addresses`, action: 'list' },
{ resource: `/wallets/${walletId}/transactions`, action: 'get' },
{ resource: `/wallets/${walletId}/transactions`, action: 'list' },
{ resource: `/wallets/${walletId}/spend-requests`, action: 'list' },
{ resource: `/wallets/${walletId}/spend-requests`, action: 'get' },
],
},
{
permissionIdentifier: 'p2',
description: 'Create spend requests',
rules: [{ resource: `/wallets/${walletId}/spend-requests`, action: 'add' }],
},
{
permissionIdentifier: 'p3',
description: 'Review proposals',
rules: [
{
resource: '/proposals',
action: 'review',
filter: `proposal.wallet_id == '${walletId}'`,
},
],
},
],
}
}Wallet Viewer (Per-Wallet Access)
function getWalletViewerRules(walletId: string) {
return {
roleIdentifier: 'wallet-viewer',
permissions: [
{
permissionIdentifier: 'p1',
description: 'View wallet resources',
rules: [
{ resource: `/wallets/${walletId}`, action: 'get' },
{ resource: `/wallets/${walletId}/balances`, action: 'get' },
{ resource: `/wallets/${walletId}/addresses`, action: 'get' },
{ resource: `/wallets/${walletId}/addresses`, action: 'list' },
{ resource: `/wallets/${walletId}/transactions`, action: 'get' },
{ resource: `/wallets/${walletId}/transactions`, action: 'list' },
{ resource: `/wallets/${walletId}/spend-requests`, action: 'list' },
{ resource: `/wallets/${walletId}/spend-requests`, action: 'get' },
],
},
],
}
}Dynamic Wallet Role Assignment
Wallet-level roles (Wallet Maintainer, Standard Wallet User, Wallet Viewer) are dynamically assigned per wallet. When a user is granted a wallet role, the system generates rules specific to that wallet ID.
Assigning Wallet Roles
// 1. Create wallet-specific rules
const walletId = 'abc-123-def'
const rules = []
// Create view rule
const viewRule = await broadcastRequest({
action: 'add',
resource: '/rules',
details: {
rlid: uuidv4(),
name: `view-wallet-${walletId}`,
resource: `/wallets/${walletId}`,
action: 'get',
description: `View wallet ${walletId}`,
},
})
rules.push(viewRule.details.rlid)
// Create balance rule
const balanceRule = await broadcastRequest({
action: 'add',
resource: '/rules',
details: {
rlid: uuidv4(),
name: `view-wallet-${walletId}-balances`,
resource: `/wallets/${walletId}/balances`,
action: 'get',
description: `View balances for wallet ${walletId}`,
},
})
rules.push(balanceRule.details.rlid)
// Create spend-request rule
const spendRule = await broadcastRequest({
action: 'add',
resource: '/rules',
details: {
rlid: uuidv4(),
name: `spend-wallet-${walletId}`,
resource: `/wallets/${walletId}/spend-requests`,
action: 'add',
description: `Create spend requests for wallet ${walletId}`,
},
})
rules.push(spendRule.details.rlid)
// 2. Create role for wallet access
const walletRole = await broadcastRequest({
action: 'add',
resource: '/roles',
details: {
rid: uuidv4(),
name: `wallet-${walletId}-user`,
description: `Standard user access to wallet ${walletId}`,
},
})
// 3. Add rules to role
await broadcastRequest({
action: 'edit',
resource: `/roles/${walletRole.details.rid}/rules/add`,
details: {
rules: rules,
},
})
// 4. Assign user to role
await broadcastRequest({
action: 'edit',
resource: `/roles/${walletRole.details.rid}/users/add`,
details: {
users: [userId],
},
})