IsolatedSites Module for Omeka S
The IsolatedSites module is a comprehensive security and access control solution for Omeka S that enforces content isolation based on site permissions. It ensures users can only view and interact with resources (items, item sets, media, assets, and sites) belonging to sites they are explicitly granted access to, significantly enhancing security and usability in multi-site, multi-user environments.
The module achieves this through role-based access control with a specialized site_editor role, user-configurable scope limitation settings, and full API integration for programmatic access management. This allows organizations to maintain strict data boundaries between different sites and users while preserving a streamlined administrative experience for site editors and content managers.
✨ Features
- User Setting Options ⚙️:
- Two flags are added per user:
limit_to_granted_siteslimit_to_own_assets
-
These options are available in each user's settings (
Profiles → User Settings):- 🔒 Limit to granted sites:
- Items and Item Sets assigned to sites where the logged-in user has no role are filtered out from the admin browse pages.
- In the Admin Dashboard and under the "Sites" navigation menu, only the sites where the user has assigned roles are shown.
- 📄 Limit assets list to my own assets:
- Assets not owned by the logged-in user are hidden from the admin browse page.
-
Site Editor Role 🎭:
- A specialized
site_editorrole for site-scoped content management. - Inherits core
editorcapabilities but restricts access to only assigned sites. - Users can view and edit Item Sets they own and those included in sites with granted access.
- SiteAdmin permissions configured to allow access to the Resources tab for adding Item Sets while restricting other administrative actions.
-
Ideal for organizations with multiple sites requiring strict content isolation between teams.
-
Full API Integration 🔌:
- Custom user settings (
limit_to_granted_sites,limit_to_own_assets) are fully accessible via REST and PHP APIs. - Programmatic management of user permissions and scope settings.
- Seamless integration with existing Omeka S API workflows.
-
See the API Integration section below for detailed usage examples.
-
Automatic Filtering:
- When enabled, content filtering is automatic without requiring any manual user action.
-
Resource queries are filtered at the API level for consistent behavior.
-
Admin Exemption:
- Global administrators retain unrestricted access to all content, regardless of the settings.
-
Ensures system administrators can always perform maintenance and troubleshooting.
-
Docker Compose for Easy Testing 🐳:
- A simple Docker environment is included for fast testing and development.
🚀 Installation
Manual Installation
- Download the latest release from GitHub.
- Extract the ZIP file into your Omeka S
modulesdirectory. - In the Omeka S Admin Panel, navigate to Modules, find IsolatedSites, and click Install.
Using Docker (for testing)
A docker-compose.yml file is provided:
# Make sure you have Docker and Docker Compose installed
git clone https://github.com/ateeducacion/omeka-s-IsolatedSites.git
cd omeka-s-IsolatedSites
make up
-
Wait for the containers to start (this may take a minute).
-
Access Omeka S at http://localhost:8080.
-
Log in as admin (
admin@example.com/PLEASE_CHANGEME).
🧪 Verifying site isolation (local Docker)
On first boot the Docker environment provisions a ready-made multi-site scenario
(see data/provision-demo.php) so the isolation can be checked end to end:
| User | Password | Role | Scope | |
|---|---|---|---|---|
| Editor (control) | editor@example.com |
1234 |
editor |
No isolation — sees everything |
| Site Researcher A | siteresearcher.a@example.com |
1234 |
site_researcher |
site-a, read-only |
| Site Editor A | siteeditor.a@example.com |
1234 |
site_editor |
site-a, manages content (not the site) |
| Site Manager A | sitemanager.a@example.com |
1234 |
site_manager |
site-a, content and site/pages |
| Site Editor B | siteeditor.b@example.com |
1234 |
site_editor |
site-b, manages content |
Each site has two items and an item set. The
Impersonate module is also
installed so you can switch into any of these users from the admin user list
(or with ?login_as=<userId>) without juggling passwords. To verify:
- Impersonate Site Editor A → admin Items / Item sets / Sites show only site-a; site-b is hidden. They can add/edit items but the page editor is blocked.
- Impersonate Site Manager A → same isolation, but they can edit site-a's pages, title and navigation.
- Impersonate Site Researcher A → sees site-a content read-only (no add/edit buttons).
- Impersonate Site Editor B → the mirror image (only site-b).
- Editor / admin → everything is visible.
- Confirm the same filtering applies over the REST API, e.g.
GET /api/itemsauthenticated as Site Editor A returns only their items.
Playground: the browser playground provisions the same scenario from
blueprint.json(sites site-a / site-b withsite_researcher/site_editor/site_managerusers, per-site permissions, thelimit_to_granted_sitesuser setting, and the Impersonate module). Open the Try in your browser link and impersonate the demo users above (passwordpasswordin the playground) to compare the three roles. Multi-site blueprints require an up-to-date playground build.
🛠️ Usage
After installing the module:
- Go to Profiles → User Settings.
- Enable the options:
- Limit to granted sites
- Limit assets list to my own assets
- Save changes.
Depending on the settings enabled, the admin interface will be dynamically filtered to show only the permitted resources.
📋 Requirements
- Omeka S version 4.x or later
- PHP 7.4 or newer
- Composer (only for building or developing)
🧩 Technical Notes (Summary)
- New User Settings: Two flags are added per user:
limit_to_granted_siteslimit_to_own_assets- Event Listeners:
- Listeners attached to
api.search.queryevents filter the resources dynamically at query time. - API event listeners handle custom settings in user API operations.
- Resource Filters:
- Items: Filtered based on granted sites.
- Item Sets: Filtered based on granted sites and ownership.
- Assets: Filtered based on ownership.
- Sites: Filtered based on granted site permissions.
- Admin Users: Administrators are exempt from restrictions.
- API Integration: Custom user settings are accessible through both REST API and PHP API.
- No Permission Changes: This module only changes admin UI visibility and adds API access to custom settings, it does not alter underlying Omeka S permission checks.
🔌 API Integration
The custom user settings (limit_to_granted_sites, limit_to_own_assets) are fully integrated with Omeka-S API:
REST API Usage
Reading user data (GET /api/users/{id}):
{
"o:id": 1,
"o:name": "John Doe",
"o:email": "john@example.com",
"o:role": "editor",
"o:is_active": true,
"o-module-isolatedsites:limit_to_granted_sites": true,
"o-module-isolatedsites:limit_to_own_assets": false
}
Updating user data (PUT /api/users/{id}):
{
"o:name": "Updated Name",
"o-module-isolatedsites:limit_to_granted_sites": false,
"o-module-isolatedsites:limit_to_own_assets": true
}
PHP API Usage
Using Service Manager in $service and api in $api Omeka/ApiManager $response = $api->read('users', $ID); $user = $response->getContent(); $userSettingsService = $services->get('Omeka\Settings\User'); $userSettingsService->setTargetId($user->id());
$userSettingsService->get('limit_to_granted_sites', false) $userSettingsService->get('limit_to_own_assets', false)
Updating settings:
$api->update('users', 1, [
'o:name' => 'Updated Name',
'o-module-isolatedsites:limit_to_granted_sites' => true,
'o-module-isolatedsites:limit_to_own_assets' => false
],[],'isPartial'=> true);
Note: For PHP API calls, custom settings must be accessed via getJsonLd() or helper methods. See API_INTEGRATION_README.md for complete documentation.
📄 License
This module is released under the GNU General Public License v3.0 (GPL-3.0).
📬 Support
For questions, suggestions, or contributions, please open an Issue or submit a Pull Request.
Site-scoped Roles
The module adds three site-scoped roles. All three are isolated to the sites a
user is granted on (via the limit_to_granted_sites setting); they differ only in
what they can write:
| Role | Inherits | Can do | Cannot do |
|---|---|---|---|
site_researcher |
researcher |
Read items, item sets, media and pages of their granted sites | Create or edit any content; edit the site |
site_editor |
editor |
Everything site_researcher can plus create/edit/delete content (items, item sets, media) reachable through a granted site (or owned) |
Edit the site itself — pages, title, navigation, theme |
site_manager |
editor |
Everything site_editor can plus edit the site — pages, title, navigation and theme — of their granted sites |
Create or delete sites; manage a site's user permissions |
In short: site_editor manages content, site_manager also manages the site, and
site_researcher is read-only. None of them can create/delete sites, manage other
users, change resource templates, or see system information — those stay with global
administrators.
Permission Comparison
| Capability | editor (core) | site_researcher | site_editor | site_manager |
|---|---|---|---|---|
| Read items / item sets / media | All sites | Granted sites only | Granted sites only | Granted sites only |
| Create / edit content | All sites | ❌ | ✅ (granted sites / owned) | ✅ (granted sites / owned) |
| Edit pages, title, navigation, theme | All sites | ❌ | ❌ | ✅ (granted sites) |
| Create / delete sites | ✅ | ❌ | ❌ | ❌ |
| Manage site user permissions | ✅ | ❌ | ❌ | ❌ |
| Resource templates | Full | Read-only | Read-only | Read-only |
| User management | Any user | Own profile only | Own profile only | Own profile only |
Read isolation is enforced by the
api.search.querylisteners + thelimit_to_granted_sitesuser setting (role-independent); write isolation is enforced by the ACL rules above + the per-site access assertion. Page editing forsite_manageris additionally gated by Omeka core's per-site permission.
Configuration Checklist
The admin UI surfaces a warning whenever a content-managing site role (
site_editor/site_manager) is missing the required isolation settings.
- Assign the role in Admin > Users, then grant the user a permission for each site they should access (Sites > Permissions):
vieweris enough forsite_researcher,editor/adminforsite_editor/site_manager. - Set a Default site in Admin > Users > User settings so new items a content role creates belong to that site.
- Enable
limit_to_granted_sitesin the same panel to activate the site-based filtering. - Remind users they will only see and manage content linked to their permitted sites; content elsewhere remains hidden.