Kibana Spaces for multi-tenancy: isolate dashboards without duplicating data
Kibana Spaces partition saved objects into isolated namespaces with separate URLs and .kibana_* indices, but data access remains controlled by Elasticsearch security. Learn setup, RBAC setup, limits and common mistakes for Elastic 7.x-8.x.
03 Jul 2025, 13:33 UTC

Spaces isolate Kibana UI, not Elasticsearch data
The useful takeaway first: Kibana Spaces partition saved objects — dashboards, visualizations, index patterns, Canvas workpads — into separate namespaces with their own navigation and URL prefix /s//.
Data access is still controlled by Elasticsearch security. Spaces are for content isolation and team UX, not for data isolation.
Spaces are enabled by default since 7.7 via xpack.spaces.enabled in kibana.yml. Each space maps to its own saved-objects index, typically .kibana_. The default space id "default" always exists and cannot be deleted.
Create a space and bind it to a role
Create spaces in Stack Management → Spaces or via the Spaces API. Run from Kibana console or curl against Kibana as a user with superuser privileges.
POST /api/spaces/space
{
"id": "finance",
"name": "Finance",
"description": "Finance team dashboards"
}
Space membership is enforced through Elasticsearch role definitions, not Kibana UI alone. A minimal role for a finance analyst might look like:
{
"kibana": [
{
"spaces": ["finance"],
"privileges": ["read", "create_index_pattern", "dashboard"]
}
]
}
Assign the role to users via the Security UI or an API. Users without an explicit space assignment fall back to default if they have kibana:.kibana privileges. With SAML or OIDC, the role mapping must include space assignments, otherwise users land in default with limited privileges.
Verify the setup:
- List spaces: GET /api/spaces/space as a user with management privileges.
- Check saved-object indices: GET /_cat/indices/.kibana_*?v from Elasticsearch as a user with monitor privileges. Expect one index per space.
- Login as a test user and open /s/finance/. Only finance objects should be visible. Attempting /s/marketing/ should be denied.
Sharing objects between spaces
Index patterns are space-scoped. A pattern created in finance is invisible in marketing. To share, recreate the pattern in each space or grant read access to a shared base space.
Cross-space copy requires an explicit API call. The source space is in the URL path, the target space is supplied via header or parameter. Run as a user with privileges in both spaces.
POST /s/finance/api/saved_objects/_bulk_create
kbn-xsrf: true
space: marketing
{
"objects": [...]
}
Risk: each copy duplicates JSON in the target .kibana_ index. Monitor index sizes. Deleting a space permanently removes its saved objects with no trash bin. Snapshot .kibana_ before deletion.
Limits you will hit in production
Spaces do not isolate Elasticsearch data access. Document Level Security and Field Level Security on the Elasticsearch side are required for data isolation. Spaces only organize Kibana UI and saved objects.
Storage overhead grows with the number of spaces because each space stores its own copy of saved objects. Upgrading from pre-7.7 migrates all existing objects into default. Plan a one-time reorganization before creating many spaces.
URL bookmarks break when objects move between spaces because the space ID is part of the URL path. Plugin support varies by version. Maps, APM and other plugins may not fully respect space boundaries in older 7.x releases. Test each plugin in the target version.
Audit events for space creation, deletion and object copies are written to .security-audit-log-* when xpack.security.audit.enabled is true. Review with a query like event.action:space_created to confirm lifecycle events.
Common mistakes
- Assuming Spaces equals data isolation. Combine Spaces with Elasticsearch roles, DLS and FLS for true multi-tenancy.
- Creating index patterns per team without a shared source. This leads to drift. Consider a read-only shared space for common patterns.
- Forgetting role mapping for SSO. Users authenticate but see only default because the mapped role lacks space privileges.
- Deleting a space to "clean up" and losing dashboards permanently. Snapshot first.
Practical check after changes: confirm version support with GET /api/status and version.number >=7.7, verify space list, verify RBAC by impersonating a test user, and inspect .kibana_* index sizes to catch duplication early.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.