Skip to content

Access Control ​

Overview ​

The permissions system has two layers:

  1. Portal visibility — which brand portals a resource is visible on (replaces the old public/private toggle; managed via the "Portals" dialog)
  2. Role-based capabilities — what operations each workspace role can perform (enforced via DAM_CAPABILITIES in plugins/helper.js)

Role Hierarchy ​

Four roles exist in the DAM. There is no member role.

RoleWhoDAM Access
brand-portal-userExternal portal visitorBrand portal only
viewerRead-only workspace memberView, search, share/download, insights
managerContent managerMost operations except admin-only settings
adminWorkspace administratorFull access

DAM Capabilities Matrix ​

Source: plugins/helper.js — DAM_CAPABILITIES object. Keys are snake_case.

Basic Access ​

Capability keybrand-portal-userviewermanageradmin
brand_portal_access✓✓✓✓
help_support✓✓✓✓

Content & Upload ​

Capability keybrand-portal-userviewermanageradmin
content_upload✓✓
uncategorized_assets_bar✓✓
uncategorized_assets_folder✓✓
duplicating_content✓✓
moving_content✓✓
deleting_content✓✓
sharing_downloading✓✓✓

Folder Management ​

Capability keybrand-portal-userviewermanageradmin
creating_folders✓✓
editing_folder_name_description✓✓
folder_permission✓✓

Collage Management ​

Capability keybrand-portal-userviewermanageradmin
creating_collages✓✓
removing_collage✓✓
editing_collage_name_description✓✓
collage_permission✓✓
deleting_collage✓✓
removing_asset_from_collage✓✓

Asset Details ​

Capability keybrand-portal-userviewermanageradmin
editing_asset_name✓✓
editing_asset_description✓✓
asset_permission✓✓
viewing_insights✓✓✓

Tags ​

Capability keybrand-portal-userviewermanageradmin
adding_tags✓✓
removing_tags✓✓
viewing_tags✓✓

Custom Fields ​

Capability keybrand-portal-userviewermanageradmin
managing_custom_fields✓✓
removing_custom_fields✓✓
managing_custom_fields_settings✓
creating_new_custom_fields✓

Asset Versioning ​

Capability keybrand-portal-userviewermanageradmin
viewing_versions✓✓✓
downloading_versions✓✓✓
adding_new_versions✓✓
restoring_versions✓✓
deleting_versions✓✓

Trash ​

Capability keybrand-portal-userviewermanageradmin
restoring_trash✓✓
managing_trash✓
Capability keybrand-portal-userviewermanageradmin
search_bar✓✓✓
inner_search✓✓✓

Account Settings ​

Capability keybrand-portal-userviewermanageradmin
account_settings✓
account_admins✓
adding_users✓
manage_organization_notifications✓
viewing_announcements✓
guest_upload_manager✓

Brand Portal ​

Capability keybrand-portal-userviewermanageradmin
creating_brand_portal✓✓
managing_brand_portal_users✓✓
managing_brand_portal_banners✓✓
managing_brand_portal_tiles✓✓
controlling_brand_portal_settings✓

Share / Embed ​

Capability keybrand-portal-userviewermanageradmin
embedded_delete✓✓✓
revoke_share✓✓✓
advanced_settings✓✓✓
manage_sharing✓✓

Note: For embedded_delete, revoke_share, and advanced_settings, viewers can only act on their own shares. Managers and admins can act on any.

Helper Functions ​

All helpers are registered on Vue.prototype via plugins/helper.js and accept a workspace object as their sole argument.

javascript
// Get workspace from store
const workspace = this.$store.state.auth.user.accessibleWorkspaces
  .find(w => w.id == this.$route.params.workspace_id)

// Usage in computed properties
computed: {
  canUpload() {
    return this.$canUploadContent(workspace)
  },
  canDelete() {
    return this.$canDeleteContent(workspace)
  }
}

Complete Helper Reference ​

Vue prototype methodCapability key checked
$canUploadContent(workspace)content_upload
$canDeleteContent(workspace)deleting_content
$canShareDownload(workspace)sharing_downloading
$canMoveContent(workspace)moving_content
$canDuplicateContent(workspace)duplicating_content
$canCreateFolders(workspace)creating_folders
$canEditFolderNameDescription(workspace)editing_folder_name_description
$canManageFolderPermission(workspace)folder_permission
$canCreateCollages(workspace)creating_collages
$canRemoveCollage(workspace)removing_collage
$canEditCollageNameDescription(workspace)editing_collage_name_description
$canManageCollagePermission(workspace)collage_permission
$canDeleteCollage(workspace)deleting_collage
$canRemoveAssetFromCollage(workspace)removing_asset_from_collage
$canEditAssetName(workspace)editing_asset_name
$canEditAssetDescription(workspace)editing_asset_description
$canManageAssetPermission(workspace)asset_permission
$canViewInsights(workspace)viewing_insights
$canAddTags(workspace)adding_tags
$canRemoveTags(workspace)removing_tags
$canViewTags(workspace)viewing_tags
$canManageCustomFields(workspace)managing_custom_fields
$canRemoveCustomFields(workspace)removing_custom_fields
$canManageCustomFieldsSettings(workspace)managing_custom_fields_settings
$canCreateNewCustomFields(workspace)creating_new_custom_fields
$canAddNewVersions(workspace)adding_new_versions
$canViewVersions(workspace)viewing_versions
$canRestoreVersions(workspace)restoring_versions
$canDeleteVersions(workspace)deleting_versions
$canDownloadVersions(workspace)downloading_versions
$canRestoreTrash(workspace)restoring_trash
$canManageTrash(workspace)managing_trash
$canUseSearchBar(workspace)search_bar
$canUseInnerSearch(workspace)inner_search
$canAccessAccountSettings(workspace)account_settings
$canManageAccountAdmins(workspace)account_admins
$canAddUsers(workspace)adding_users
$canManageNotifications(workspace)manage_organization_notifications
$canViewAnnouncements(workspace)viewing_announcements
$canCreateBrandPortal(workspace)creating_brand_portal
$canManageBrandPortalSettings(workspace)controlling_brand_portal_settings
$canManageBrandPortalUsers(workspace)managing_brand_portal_users
$canManageBrandPortalBanners(workspace)managing_brand_portal_banners
$canManageBrandPortalTiles(workspace)managing_brand_portal_tiles
$canViewUncategorizedAssetsBar(workspace)uncategorized_assets_bar
$canViewUncategorizedAssetsFolder(workspace)uncategorized_assets_folder
$canAccessHelpSupport(workspace)help_support

Core Function ​

javascript
// plugins/helper.js
const canPerformDamOperation = (workspace, operation) => {
  if (!workspace || !operation) return false
  const allowedRoles = DAM_CAPABILITIES[operation]
  if (!allowedRoles) return false
  const user = getUserModulesAndRoles(workspace)
  if (!user || !user.hasDamAccess || !user.dam.role) return false
  return allowedRoles.includes(user.dam.role.toLowerCase())
}

The workspace object must come from accessibleWorkspaces (store) — it contains the user's role for that workspace. Never pass a plain workspace ID.

Resource Visibility Components ​

These manage which portals content is published to. There is no longer a binary public/private toggle.

components/dam/Dialogs/PermissionDialog.vue — "Portals" dialog ​

Completely redesigned. Title is "Portals". Shows a list of portals with per-portal toggle switches. Users select which portals a resource is visible on.

  • Old behavior (main branch): public/private radio buttons
  • New behavior (development branch): portal list, multiple-select toggles, instance_ids array in payload

Capability required: folder_permission / asset_permission / collage_permission

Key change: AssetPermissionDialog.vue was deleted — there is no separate asset confirmation dialog.

API payload:

javascript
POST /digital-assets/permission/change-permission
{
  workspace_id,
  visibility: 0,              // 0 = visible on selected portals
  instance_ids: [portalId1, portalId2],
  asset_ids: [...],           // plural arrays (bulk support)
  category_ids: [...],
  collection_ids: [...],
  nested_apply: 0 | 1,        // folders only
}

See Permission Dialog component for full props and usage.

components/dam/StaticPermissionDialog.vue ​

Shown when the user's plan does not permit portal visibility changes. Displays an upgrade CTA.

Middleware ​

Middleware fileWhat it checks
middleware/can-access-dam-module.jsUser has brand_portal_access or higher for the workspace
middleware/can-access-dam-settings.jsUser has account_settings capability (admin only)

Usage Pattern in Components ​

vue
<template>
  <v-btn
    v-if="canCreate"
    :ripple="false"
    @click="openCreateDialog"
  >
    New Folder
  </v-btn>
</template>

<script>
export default {
  computed: {
    workspace() {
      return this.$store.state.auth.user?.accessibleWorkspaces
        ?.find(w => w.id == (this.$route.params.workspace_id || this.$getWorkspaceId()))
    },
    canCreate() {
      return this.$canCreateFolders(this.workspace)
    },
    canDelete() {
      return this.$canDeleteContent(this.workspace)
    },
    canShare() {
      return this.$canShareDownload(this.workspace)
    }
  }
}
</script>