Configure Kibana Spaces for Team‑Based Isolation with RBAC
Step‑by‑step guide to enabling Kibana Spaces, creating team‑specific spaces, defining Elasticsearch roles with space‑scoped Kibana privileges, mapping users, and verifying isolation. Includes configuration snippets, API examples, and recovery procedures.
03 Apr 2026, 22:30 UTC

Problem and Takeaway
Multiple teams sharing a single Kibana instance often need separate dashboards, visualizations, and saved objects without seeing each other's work. Kibana Spaces provides logical isolation, but it must be paired with Elasticsearch role‑based access control (RBAC) to enforce boundaries. This guide walks through enabling spaces, creating team‑specific spaces, defining roles that grant access to specific space IDs, mapping users, and verifying the isolation works.
Prerequisites
- Kibana 7.10 or later with Elasticsearch security enabled (xpack.security.enabled: true).
- A user account with superuser or manage_security cluster privileges.
- Existing Elasticsearch roles that define index‑level data permissions for each team (spaces do not enforce data‑level security).
- Access to kibana.yml on each Kibana node and the Kibana UI (Management > Spaces).
Enable Spaces in Configuration
Edit kibana.yml on every Kibana node and restart the service:
xpack.spaces.enabled: true
After restart, the space selector appears in the top navigation bar. If you run a multi‑node cluster, apply the change to all nodes before restarting any.
Create Team Spaces
- Open Kibana as a superuser and go to Management > Spaces.
- Click Create space.
- Enter a unique space ID (lowercase, no spaces) and a display name. Example IDs:
infra,security,business. - Optionally add a description and avatar, then save.
Repeat for each team. The space ID is used in role definitions and API calls; the display name appears in the UI selector.
Define Elasticsearch Roles with Kibana Privileges
Create a role per team that grants Kibana read/write access to its space ID. Use the Kibana UI (Management > Security > Roles) or the Elasticsearch API. Example role for the infra team via API (run on Elasticsearch cluster with manage_security privilege):
PUT /_security/role/kibana_infra
{
cluster: ['monitor'],
indices: [
{
names: ['infra-*', 'metrics-*'],
privileges: ['read', 'view_index_metadata']
}
],
applications: [
{
application: 'kibana-.kibana',
privileges: ['space_read', 'space_write'],
resources: ['space:infra']
}
]
}
Adjust the index patterns (infra-*, metrics-*) to match your team's data indices. Create analogous roles for security and business with their respective space IDs and index patterns.
Map Users to Roles
Assign users to the appropriate role using the native realm or your SAML/LDAP integration. In Kibana UI: Management > Security > Users > select user > Edit > add role kibana_infra. Alternatively, use the Elasticsearch role mapping API for automated provisioning.
Populate Spaces with Dashboards and Saved Objects
- Switch to the target space using the space selector (top left).
- Create index patterns, visualizations, and dashboards as usual. Objects created while a space is active are automatically scoped to that space.
- To migrate existing objects, use the Saved Objects Export/Import APIs with the
space_idheader. Example export from default space:
GET /api/saved_objects/_export?type=dashboard&space_id=default
Authorization: Basic <superuser_credentials>
Then import into the infra space:
POST /api/saved_objects/_import?space_id=infra
Content-Type: application/ndjson
Authorization: Basic <superuser_credentials>
<exported_ndjson_payload>
Expected Checks
- Space selector: Log in as a user mapped to kibana_infra. The selector should show only infra (and possibly the default space if the role includes it).
- Direct URL access: Attempt to open a dashboard URL from the security space (e.g., /s/security/app/dashboards#/view/abc123) while logged in as an infra user. Expect a redirect to an unauthorized page or a 403 response.
- API verification: Run
GET /api/saved_objects/_find?space_id=infrawith the infra user's credentials. The response should list only objects in the infra space. The same call with space_id=security should return 403.
Recovery Options
- User locked out: Use a superuser account to adjust role mappings or add the user to a role that grants access to the needed space.
- Space metadata corruption: Restore the .kibana_task_manager and .kibana indices from a recent snapshot. This reverts all spaces to the snapshot state.
- Move objects between spaces: Use the Saved Objects Export/Import APIs with the target space_id as shown above. This is a manual operation; there is no bulk move UI.
Limitations and Cautions
- No data‑level security: Spaces isolate UI objects only. Index‑level permissions must be enforced via Elasticsearch roles (as shown in the role definition). A user with access to the infra space but no index privileges on infra-* will see dashboards but no data.
- Disabling spaces is destructive: Setting
xpack.spaces.enabled: falseafter creating spaces leaves space‑specific saved objects orphaned. Manual cleanup of .kibana documents with space_id fields is required. Treat this as irreversible for existing spaces. - Cross‑space references break: Markdown visualizations or dashboard links that reference objects in another space will fail if the target space is inaccessible to the user.
- Upgrade testing: Kibana upgrades may change space migration behavior. Validate upgrades in a staging environment before production.
Practical Verification Checklist
- Log in as infra user; confirm only infra dashboards appear.
- Attempt direct URL access to a security dashboard; verify 403/redirect.
- Run
GET /api/saved_objects/_find?space_id=infraprogrammatically; confirm object list matches UI. - Check that index‑level permissions work: infra user queries infra-* indices successfully, but queries on security-* return index_not_found_exception or 403.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.