In this tutorial you will:
synGetPermissions()
and synGetAcl()synGetAcl()synSetPermissions()synListAcl()synDeletePermissions()PRINCIPAL_ID in the tutorial script before running it. This
should be a Synapse user ID or team ID that you want to grant
permissions to.Before we begin, it’s important to understand the different permission types available in Synapse:
Understanding how permissions work in Synapse is crucial for effective ACL management:
Every entity in Synapse has a benefactor - the entity from which it inherits its permissions. When checking permissions for an entity:
While this tutorial focuses on Folders, you can apply the same
permission management functions (synGetPermissions(),
synGetAcl(), synSetPermissions(),
synListAcl(), and synDeletePermissions()) to
other Synapse entities including:
The inheritance and benefactor concepts apply consistently across all entity types in Synapse.
IMPORTANT: Before running the tutorial, you MUST
edit the script to set a valid PRINCIPAL_ID.
library(synapser)
# REQUIRED: Set this to the Synapse user ID or team ID you want to grant permissions to
# Do NOT leave this as NULL - the script will not work properly
PRINCIPAL_ID <- NULL # Replace with actual user/team ID, e.g. 273948L
if (is.null(PRINCIPAL_ID)) {
stop(
"You must set PRINCIPAL_ID to a valid Synapse user ID or team ID before running this script. ",
"Examples: ###### (user ID), 273948 (authenticated users), 273949 (public)"
)
}
# Helper to print a list of permissions on one line
format_permissions <- function(x) paste(unlist(x), collapse = ", ")
synLogin()
# Step 1: Get or create a project for this tutorial
cat("=== Step 1: Getting project ===\n")
project <- Project(name = "My uniquely named project about Alzheimer's Disease") |> synGet()# Step 2: Create a main folder to set custom sharing settings
cat("\n=== Step 2: Creating main to set custom permissions ===\n")
main_folder <- Folder(
name = "Research Data",
description = "Main folder for research data with custom sharing settings",
parent_id = project$id
) |> synStore()
cat(sprintf("Created main folder: %s (ID: %s)\n", main_folder$name, main_folder$id))The synGetPermissions() function returns the permissions
that the current user has on an entity
# Step 3: Demonstrate synGetPermissions() - Get current user's permissions
cat("\n=== Step 3: Getting current user's permissions ===\n")
permissions <- main_folder |> synGetPermissions()
cat(sprintf(
"Current user permissions on main folder: %s\n",
format_permissions(permissions$access_types)
))You’ll notice the output looks like:
=== Step 3: Getting current user's permissions ===
Current user permissions on main folder: READ, UPDATE, CREATE, DELETE, DOWNLOAD, MODERATE, CHANGE_PERMISSIONS, CHANGE_SETTINGS
The synGetAcl() function gets the specific permissions
for a given principal (user or team):
# Step 4: Demonstrate synGetAcl() - Get ACL for specific principal
cat("\n=== Step 4: Getting ACL for specific principal ===\n")
# First check what permissions the principal currently has (likely inherited from project)
current_acl <- main_folder |> synGetAcl(principal_id = PRINCIPAL_ID, check_benefactor = TRUE)
cat(sprintf(
"Principal %s current permissions (including inherited): %s\n",
PRINCIPAL_ID, format_permissions(current_acl)
))
# Check ACL only on the folder itself (not inherited)
folder_only_acl <- main_folder |> synGetAcl(principal_id = PRINCIPAL_ID, check_benefactor = FALSE)
cat(sprintf(
"Principal %s permissions on folder only: %s\n",
PRINCIPAL_ID, format_permissions(folder_only_acl)
))Depending on if you’ve already given permissions to given user/team you may see different results in the output.
You’ll notice the output looks like:
=== Step 4: Getting ACL for specific principal ===
Principal ######## current permissions (including inherited):
Principal ######## permissions on folder only:
Use synSetPermissions() to grant specific permissions to
a user or team:
# Step 5: Demonstrate synSetPermissions() - Set specific permissions for the main folder
cat("\n=== Step 5: Setting permissions on main folder ===\n")
main_folder_permissions <- list("READ", "DOWNLOAD")
main_folder |> synSetPermissions(
principal_id = PRINCIPAL_ID,
access_type = main_folder_permissions,
modify_benefactor = FALSE, # Create local ACL for this folder
overwrite = TRUE
)
cat(sprintf(
"Set permissions for principal %s on main folder: %s\n",
PRINCIPAL_ID, format_permissions(main_folder_permissions)
))
# Verify the permissions were set
new_acl <- main_folder |> synGetAcl(principal_id = PRINCIPAL_ID, check_benefactor = FALSE)
cat(sprintf("Verified new permissions: %s\n", format_permissions(new_acl)))You’ll notice the output looks like:
=== Step 5: Setting permissions on main folder ===
[WARNING] Creating an ACL for entity syn#######, which formerly inherited access control from a benefactor entity, "My uniquely named project about Alzheimer's Disease" (syn########).
Set permissions for principal ####### on main folder: READ, DOWNLOAD
Verified new permissions: DOWNLOAD, READ
Create a sub-folder and give it more restrictive permissions than its parent:
# Step 6: Create a sub-folder with different sharing settings
cat("\n=== Step 6: Creating sub-folder with different permissions ===\n")
sub_folder <- Folder(
name = "Sensitive Analysis",
description = "Sub-folder with more restrictive permissions",
parent_id = main_folder$id
) |> synStore()
cat(sprintf("Created sub-folder: %s (ID: %s)\n", sub_folder$name, sub_folder$id))
# Set more restrictive permissions on the sub-folder
sub_folder_permissions <- list("READ") # More restrictive - only read access
sub_folder |> synSetPermissions(
principal_id = PRINCIPAL_ID,
access_type = sub_folder_permissions,
modify_benefactor = FALSE,
overwrite = TRUE
)
cat(sprintf(
"Set more restrictive permissions for principal %s on sub-folder: %s\n",
PRINCIPAL_ID, format_permissions(sub_folder_permissions)
))You’ll notice the output looks like:
=== Step 6: Creating sub-folder with different permissions ===
Created sub-folder: Sensitive Analysis (ID: syn#######)
[WARNING] Creating an ACL for entity syn#######, which formerly inherited access control from a benefactor entity, "Research Data" (syn#######).
Set more restrictive permissions for principal ####### on sub-folder: READ
Use synListAcl() to see all the permissions in your
hierarchy. By specifying the log_tree = TRUE argument for
the function we can get an ascii tree representation of the ACLs on the
project. Alternatively you will also be able to loop over the data.
# Step 7: Demonstrate synListAcl() - List all ACLs
cat("\n=== Step 7: Listing ACLs ===\n")
# List ACLs recursively for main folder and all contents
cat("Folder ACL:\n")
recursive_acl_result <- main_folder |> synListAcl(
recursive = TRUE,
include_container_content = TRUE,
log_tree = TRUE # This will also log the tree structure
)
cat(sprintf("Folder (%s) ACL entries:\n", main_folder$id))
for (entity_acl in recursive_acl_result$all_entity_acls) {
cat(sprintf("\nEntity %s ACL:\n", entity_acl$entity_id))
for (acl_entry in entity_acl$acl_entries) {
cat(sprintf(
" Principal %s: %s\n",
acl_entry$principal_id, format_permissions(acl_entry$permissions)
))
}
}You’ll notice the output looks like:
=== Step 7: Listing ACLs ===
ACL Tree Structure:
🔍 Legend:
🔒 = No local ACL (inherits from parent)
🔑 = Local ACL (custom permissions)
└── 🔑 Research Data (syn#######) [Folder]
└── user_name_1 (#######): CHANGE_PERMISSIONS, DOWNLOAD, CHANGE_SETTINGS, MODERATE, READ, DELETE, CREATE, UPDATE
└── team_name_1 (#######): DOWNLOAD, READ
└── 🔑 Sensitive Analysis (syn#######) [Folder]
└── user_name_1 (#######): CHANGE_PERMISSIONS, UPDATE, READ, DELETE, MODERATE, CHANGE_SETTINGS, DOWNLOAD, CREATE
└── team_name_1 (#######): READ
Folder (syn#######) ACL entries:
Entity syn####### ACL:
Principal #######: CHANGE_PERMISSIONS, DOWNLOAD, CHANGE_SETTINGS, MODERATE, READ, DELETE, CREATE, UPDATE
Principal #######: DOWNLOAD, READ
Entity syn####### ACL:
Principal #######: CHANGE_PERMISSIONS, UPDATE, READ, DELETE, MODERATE, CHANGE_SETTINGS, DOWNLOAD, CREATE
Principal #######: READ
Using overwrite = FALSE will allow you to add
Permissions Non-destructively.
Note: The default behavior is
overwrite = TRUE which will replace the permissions for the
given Principal.
# Step 8: Demonstrate additional synSetPermissions() options
cat("\n=== Step 8: Demonstrating additional permission options ===\n")
# Add permissions non-destructively (overwrite = FALSE)
cat("Adding additional permissions non-destructively...\n")
main_folder |> synSetPermissions(
principal_id = PRINCIPAL_ID,
access_type = list("UPDATE"), # Add UPDATE permission
overwrite = FALSE # Don't overwrite existing permissions
)
# Verify the permissions were added
updated_acl <- main_folder |> synGetAcl(principal_id = PRINCIPAL_ID)
cat(sprintf("Updated permissions after adding UPDATE: %s\n", format_permissions(updated_acl)))You’ll notice the output looks like:
=== Step 8: Demonstrating additional permission options ===
Adding additional permissions non-destructively...
Updated permissions after adding UPDATE: READ, DOWNLOAD, UPDATE
Remove permissions for a specific principal by setting an empty access type list:
# Step 9: Demonstrate permission removal using synSetPermissions() with an empty list
cat("\n=== Step 9: Removing specific permissions ===\n")
cat(sprintf(
"Before removal - Principal %s permissions: %s\n",
PRINCIPAL_ID, format_permissions(main_folder |> synGetAcl(principal_id = PRINCIPAL_ID))
))
# Remove permissions for specific principal by setting an empty access_type
main_folder |> synSetPermissions(
principal_id = PRINCIPAL_ID,
access_type = list(), # Empty list removes all permissions for this principal
overwrite = TRUE
)
removed_acl <- main_folder |> synGetAcl(principal_id = PRINCIPAL_ID)
cat(sprintf(
"After removal - Principal %s permissions: %s\n",
PRINCIPAL_ID, format_permissions(removed_acl)
))You’ll notice the output looks like:
=== Step 9: Removing specific permissions ===
Before removal - Principal ####### permissions: READ, DOWNLOAD, UPDATE
After removal - Principal ####### permissions:
Use synDeletePermissions() to remove entire ACLs and
revert to inheritance:
# Step 10: Demonstrate synDeletePermissions() with dry run
cat("\n=== Step 10: Demonstrating synDeletePermissions() ===\n")
# First, let's set some permissions back so we have something to delete
sub_folder |> synSetPermissions(principal_id = PRINCIPAL_ID, access_type = list("READ", "UPDATE"))
cat("Re-added permissions to sub-folder for demonstration\n")
# Dry run - see what would be deleted without actually deleting
cat("\nDry run - showing what would be deleted:\n")
sub_folder |> synDeletePermissions(dry_run = TRUE, show_acl_details = TRUE)
# Actually delete the permissions (this will make the sub-folder inherit from parent)
cat("\nActually deleting ACL from sub-folder:\n")
sub_folder |> synDeletePermissions(include_self = TRUE)
# Verify inheritance
inherited_acl <- sub_folder |> synGetAcl(principal_id = PRINCIPAL_ID)
cat(sprintf("Sub-folder now inherits permissions: %s\n", format_permissions(inherited_acl)))You’ll notice the output looks like:
=== Step 10: Demonstrating synDeletePermissions() ===
Re-added permissions to sub-folder for demonstration
Dry run - showing what would be deleted:
=== DRY RUN: Permission Deletion Impact Analysis ===
📊 Summary: 1 entities with local ACLs to delete, 1 entities will change inheritance
🔍 Legend:
⚠️ = Local ACL will be deleted
🚫 = Local ACL will NOT be deleted
↗️ = Currently inherits permissions
🔒 = No local ACL (inherits from parent)
🔑 = Permission that will be removed
📍 = New inheritance after deletion
Sensitive Analysis (syn#######) [Folder] ⚠️ WILL DELETE LOCAL ACL → Will inherit from syn#######
├── 🔑 user_name_1 (#######): ['CHANGE_SETTINGS', 'MODERATE', 'DELETE', 'READ', 'DOWNLOAD', 'UPDATE', 'CHANGE_PERMISSIONS', 'CREATE'] → WILL BE REMOVED
└── 🔑 team_name_1 (#######): ['READ', 'UPDATE'] → WILL BE REMOVED
=== End of Dry Run Analysis ===
Actually deleting ACL from sub-folder:
Sub-folder now inherits permissions:
Get a complete view of your permission structure:
# Step 11: Final ACL overview
cat("\n=== Step 11: Final ACL overview ===\n")
final_overview <- main_folder |> synListAcl(
recursive = TRUE, include_container_content = TRUE, log_tree = TRUE
)You’ll notice the output looks like:
=== Step 11: Final ACL overview ===
ACL Tree Structure:
🔍 Legend:
🔒 = No local ACL (inherits from parent)
🔑 = Local ACL (custom permissions)
└── 🔑 Research Data (syn#######) [Folder]
└── user_name_1 (#######): CHANGE_PERMISSIONS, DOWNLOAD, CHANGE_SETTINGS, MODERATE, READ, DELETE, CREATE, UPDATE
synGetPermissions(): Get current
user’s effective permissionssynGetAcl(): Get specific principal’s
permissions on an entitysynSetPermissions(): Set permissions
for a principalsynListAcl(): List all ACLs in a
hierarchysynDeletePermissions(): Remove ACLs
and revert to inheritancedry_run = TRUE before deleting
permissionssynListAcl() to audit your permission
structuresynDeletePermissions() to revert to parent
permissions when needed