Enterprise

RBAC & access control: policy grants, ACLs, groups

Wikantik enforces access control at three layers — role-level policy grants stored in the database, page-level ACLs written inline in page content, and managed groups — all checked consistently across the UI, REST API, and every admin surface.

Layers of access control

Most wiki platforms have one or two access knobs: "can edit" and "can admin." Wikantik has a full permission model because the situations that enterprise teams actually face — restricting a sensitive runbook to a single team, granting an external user read-only access, letting a bot write without giving it delete rights — require genuine granularity.

The three layers compose cleanly: policy grants set the baseline for each role, page ACLs override the baseline for individual pages, and groups make it practical to assign permissions to teams rather than individuals.

The permission model

Wikantik uses JAAS-based authorization with two sets of named permissions:

Page permissions

Each page operation requires a specific permission, checked before the operation proceeds:

  • view — read the page content
  • comment — add a comment
  • edit — modify the page body
  • modify — change page metadata
  • upload — attach files
  • rename — rename or move the page
  • delete — delete the page

Wiki permissions

Broader capability permissions govern actions that span pages:

  • createPages, createGroups, editPreferences, editProfile, login

Policy grants — database-backed, UI-managed

Default role permissions are stored in the policy_grants table in PostgreSQL. The admin UI at Admin → Security (/admin/security) exposes a grid for managing these grants: which roles get which permissions by default.

Because the grants live in the database rather than a config file, changes take effect immediately — no redeploy required. An admin can tighten or loosen role defaults at runtime, and every change is visible to any query on the policy_grants table. Database-backed grants are always active when a datasource is configured, which is the default for all production deployments.

Bootstrap admin override. The wikantik.admin.bootstrap property gives the named user AllPermission for a limited window after startup (wikantik.admin.bootstrap.maxAgeSeconds, default 24 hours) so a fresh or locked-out installation can be recovered. Leave it blank once a real admin account is confirmed working.

Page-level ACLs

Individual pages can override the role-level defaults with inline ACL directives. The syntax is embedded directly in the page body:

[{ALLOW view Admin}]
[{ALLOW edit Engineering}]

This approach makes page permissions visible to anyone who can read the page source — there are no hidden configuration files to audit. An ACL line restricting view to Admin means exactly what it says: only users with the Admin role can view that page.

The REST API enforces these ACLs on every request via RestServletBase.checkPagePermission(). There is no path through the REST layer that bypasses the ACL check.

Groups

Database-backed groups (stored in groups + group_members tables) let you assign permissions to teams. You can reference a group name in a page ACL the same way you reference a role. Groups are managed through the admin UI and can be provisioned via SCIM from your IdP.

One explicit boundary: administrator access is membership of the wiki group named Admin (the default policy grants it AllPermission), and SCIM never writes that group — a SCIM create, replace, patch or delete aimed at Admin is refused with HTTP 403 and audited. All other groups, SCIM-provisioned or manual, route through GroupManager only and never modify the roles table; they carry only what policy grants and page ACLs give them. The Admin group is managed in the admin UI.

Enforced everywhere

The access control model is applied at every surface:

  • UI — the React SPA checks permissions before rendering edit controls; the server also enforces them independently.
  • REST API (/api/*) — every endpoint calls checkPagePermission() with the authenticated principal before performing any operation.
  • Admin surface (/admin/*) — protected by AdminAuthFilter, which requires AllPermission (the Admin role). No admin endpoint is reachable without it.
  • MCP servers — write tools on /wikantik-admin-mcp need a bearer API key with the mcp_admin scope; /knowledge-mcp accepts a read-only mcp_read key that cannot reach the admin surface.

Frequently asked questions

How are default role permissions managed?

Default role permissions are stored in the policy_grants table in PostgreSQL and managed through the admin UI at /admin/security. Changes take effect immediately without redeploying the application, and the full grant configuration is auditable.

Can I restrict a single page to a specific group?

Yes. Inline ACL syntax in the page body controls per-page access: [{ALLOW view Admin}] restricts view permission to the Admin role. You can combine multiple ACL lines for different permissions. The REST API enforces these ACLs via RestServletBase.checkPagePermission() on every request.

How does Wikantik prevent privilege escalation through groups?

Groups (including SCIM-provisioned groups) route exclusively through GroupManager and the groups/group_members tables. The roles table is never modified by group operations. Administrator access is membership of the wiki group named Admin, and SCIM is refused (HTTP 403) any write to that group, so an IdP cannot grant or revoke it — only the admin UI can.