#444

fix(roles): scope self-role reads by the role primary key

Openyotatameguchi-boopwants to merge intofrom

Description of the Change

Problem

Both role read handlers restrict callers without roles.view to their current role, but apply WHERE role_id = ? to the roles table. That table has an id column and no role_id column. These callers receive a database error (HTTP 500) even for their own role; looking up another role also returns 500 instead of the intended 404.

Solution

Scope both queries using roles.id = ?. Preserve unrestricted role reads for callers with roles.view and keep other roles hidden from callers without that privilege.

No linked issue.

Type of Change

  • Bug fix
  • Test update

Areas Affected

  • Core Services: REST role reads

Testing and Verification

Test Configuration

  • Base commit: 843dfeb4bfc809c09d1bc5022e567c602d8fc9dd
  • Go 1.26.5, macOS arm64, in-memory SQLite test database
  • No external database, Docker containers, or LLM calls required

Test Steps

  1. cd backend && go test ./pkg/server/services -run TestRoles_ReadsRespectTheCallersRoleScope -count=1
  2. go test ./pkg/server/services -count=1
  3. go vet ./pkg/server/services

Test Results

The full pkg/server/services suite and go vet ./pkg/server/services pass after the fix. gofmt and git diff --check are clean.

The regression test exercises own-role listing and lookup, another-role rejection, and listing/lookup with roles.view. It checks returned role IDs, list totals, and privilege ownership. Before the production fix, the three cases without roles.view return 500.

Security Considerations

Restores the existing caller-role restriction without widening access. This is an availability/correctness fix in authorization-related code; no privilege escalation is claimed. No new dependencies or permission changes.

Performance Impact

Uses the role primary key; no additional database queries.

Documentation Updates

No API schema changes.

Deployment Notes

No migrations or configuration changes. Callers without roles.view can read their own role; other-role lookups return 404.

Checklist

  • Regression coverage added
  • Affected package tests and vet pass
  • Scope and security implications described
  • No dependency or schema changes

Additional Notes

Prepared with AI assistance; validation results are recorded in this PR.