Skip to content

Split dashboard.view/dashboard.manage permissions; harden query guard - #10

Merged
pikann merged 2 commits into
masterfrom
chore/update-version
Sep 14, 2026
Merged

pikann merged 2 commits into
masterfrom
chore/update-version

Conversation

@pikann

@pikann pikann commented Sep 14, 2026

Copy link
Copy Markdown
Contributor

Summary

Every dashboard route was gated on broad, unrelated permissions (projects.read/projects.write/users.write) instead of anything dashboard-specific. Introduced dashboard.view and dashboard.manage custom permissions — each available at both project and global scope — and gated every route and the sidebar nav entries with them. dashboard.manage implies dashboard.view for loading purposes, so a manage-only role isn't blocked from the page itself.

Also hardens validateProjectScopePlaceholder in query_guard.go: the {{project_id}} filter previously just had to appear somewhere in a WHERE/ON/HAVING clause, which a duplicated/self-compared placeholder, a non-equality operator, or a sibling bare OR could all short-circuit into matching across every project. It must now appear exactly once, as a direct equality filter, with no bare OR anywhere in the query. See the updated "Authorization" and query-guard sections in README.md for the full picture.

Versioning

Bumped to 0.4.0 (minor) rather than a patch bump, since dashboard.view/dashboard.manage replace existing permission checks — an installation with roles scoped to the old permissions for dashboard access will need to grant the new ones instead.

Verification

go test ./... and go vet ./... pass, including new regression tests for the permission split and the query-guard hardening.

🤖 Generated with Claude Code

pikann and others added 2 commits September 14, 2026 08:35
… guard

Every dashboard route was gated on broad, unrelated permissions
(projects.read/projects.write/users.write) instead of anything
dashboard-specific. Introduced dashboard.view and dashboard.manage
custom permissions, each available at both project and global scope,
and gated every route and the sidebar nav entries with them.
dashboard.manage implies dashboard.view for loading purposes.

Also hardens validateProjectScopePlaceholder in query_guard.go: the
{{project_id}} filter previously just had to appear somewhere in a
WHERE/ON/HAVING clause, which a duplicated/self-compared placeholder,
a non-equality operator, or a sibling bare OR could all short-circuit
into matching across every project. It must now appear exactly once,
as a direct equality filter, with no bare OR anywhere in the query.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Minor bump: introduces dashboard.view/dashboard.manage permissions,
replacing the projects.read/projects.write/users.write checks these
routes used before (existing role grants will need to add them).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@pikann
pikann merged commit b104238 into master Sep 14, 2026
3 checks passed
@pikann
pikann deleted the chore/update-version branch September 14, 2026 09:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant