Skip to content

add internal list-permissions endpoint - #596

Open
thesujai wants to merge 3 commits into
mainfrom
sujai/age-2093-rbac-api-for-ui
Open

add internal list-permissions endpoint#596
thesujai wants to merge 3 commits into
mainfrom
sujai/age-2093-rbac-api-for-ui

Conversation

@thesujai

@thesujai thesujai commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Summary

add internal list-permissions endpoint

Closes AGE-2093

Changes

add internal list-permissions endpoint

How was this tested?

Manually calling the endpoints

Checklist

  • I have read the contributing guidelines
  • pnpm build, pnpm test, pnpm typecheck, pnpm lint:ci, and pnpm format:check pass locally
  • Tests added/updated where it makes sense
  • No hand-edits to generated code (packages/trueforge-sdk, .github/fern/openapi/openapi.json, docs/openapi.json) — fork PRs omit SDK regen; maintainers regenerate after merge
  • Docs / .env.example updated if configuration or behavior changed

Note

Medium Risk
Introduces new authorization surface area and TrueFoundry agent permission mapping; incorrect grants could mislead UIs or callers about who can manage or delete resources.

Overview
Adds POST /api/internal/list-permissions so callers can resolve MANAGE and DELETE grants for up to 100 ids at once for agents, schedules, or sessions. The response is a map keyed by resource id; ids the caller cannot access (or that do not exist) return [].

The handler wires through Authorizer.getPermissions, with new store helpers getOwnedIds (and getExternalIdsByIds for agents) to bulk-load ownership instead of per-id checks. Standalone/OIDC grants full owner permissions when created_by_subject matches the caller. TrueFoundry agents are evaluated via ServiceFoundry MANAGE_AGENT on linked external_ids; schedules and sessions still use local ownership.

OpenAPI, Fern-generated SDK (client.internal.listPermissions), and a minor bump in trueforge / trueforge-core are included.

Reviewed by Cursor Bugbot for commit 12fc774. Bugbot is set up for automated code reviews on this repo. Configure here.

@changeset-bot

changeset-bot Bot commented Sep 4, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 12fc774

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 2 packages
Name Type
@truefoundry/trueforge Minor
@truefoundry/trueforge-core Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using default effort and found 3 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 233309f. Configure here.

* Session ids among `ids` owned by `subject_id`. Empty `ids` → `[]`.
* Does **not** bump `last_activity_timestamp_ms`.
*/
getOwnedIds(input: GetOwnedIdsInput): Promise<readonly string[]>;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Store methods lack contract tests

Medium Severity

getOwnedIds was added to ISessionStore and every backend, but storeContractSuite.ts was not updated. The same gap exists for IAgentStore.getOwnedIds / getExternalIdsByIds and IScheduleStore.getOwnedIds. Shared contract coverage is what checks tenant scoping, empty ids, owner matching, and the Postgres ->> versus SQLite json_extract paths.

Additional Locations (2)
Fix in Cursor Fix in Web

Triggered by project rule: @truefoundry/trueforge-core review rules

Reviewed by Cursor Bugbot for commit 233309f. Configure here.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will add these later

data[id] = [...OWNER_RESOURCE_PERMISSIONS];
}
return data;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Admins denied schedule permissions

Medium Severity

getPermissions grants MANAGE and DELETE on schedules only when created_by_subject.subject_id matches the caller. Schedule routes already treat hasAdminRole as full access, so an OIDC admin receives empty grants for schedules they can still update or delete.

Additional Locations (1)
Fix in Cursor Fix in Web

Triggered by learned rule: Schedule RBAC is creator-or-admin; 403 vs 404

Reviewed by Cursor Bugbot for commit 233309f. Configure here.

summary: 'List permissions for resources',
description: 'Return granted actions (MANAGE, DELETE) for each requested agent, schedule, or session id.',
'x-fern-sdk-group-name': ['internal'],
'x-fern-sdk-method-name': 'list_permissions',

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Internal path is not a collection

Low Severity

The new route is POST /api/internal/list-permissions with Fern group internal and method list_permissions. Internal paths are /api/internal/{collection} (plural kebab), matching /api/internal/sessions and /api/internal/metrics. A verb in the path also freezes a non-collection SDK shape once generated.

Additional Locations (1)
Fix in Cursor Fix in Web

Triggered by project rule: @truefoundry/trueforge review rules

Reviewed by Cursor Bugbot for commit 233309f. Configure here.

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