Skip to content

Feature: Scoped API Tokens#885

Open
chrismaddalena wants to merge 62 commits into
masterfrom
feature/scoped-api-tokens
Open

Feature: Scoped API Tokens#885
chrismaddalena wants to merge 62 commits into
masterfrom
feature/scoped-api-tokens

Conversation

@chrismaddalena
Copy link
Copy Markdown
Collaborator

@chrismaddalena chrismaddalena commented May 5, 2026

CHANGELOG

[7.0.0] - 5 May 2026

Breaking Changes

  • User-managed API tokens are now opaque gwat_ credentials instead of JWTs
    • Existing user-managed JWT API tokens must be rotated to receive an opaque API token
    • API token expiry edits rotate the token prefix, secret hash, and UUID identifier, which immediately invalidates the previous credential
  • Django admin can no longer create user-bound API tokens
    • Use service principals and service tokens for non-human integrations
    • Admin-created user-bound API tokens should be replaced with user-created API tokens or scoped service tokens, depending on whether the credential should act as a user or as a non-human service
  • Login and collaborative editor JWTs now use explicit JWT typing and are accepted only by their intended authentication paths
    • General GraphQL authentication rejects collaborative editor JWTs
    • Login JWTs require a tracked, unrevoked user session bound by the jti claim
  • Service-token GraphQL access now uses the new service role and scoped service-token permissions instead of inheriting a creating user's permissions

Added

  • Scoped Service Tokens: Added service principals and service tokens for non-human automation credentials
    • Service principals represent durable integrations or automation services
    • Service tokens are opaque gwst_ credentials with hashed secrets, expiration, revocation, and last-used tracking
    • Service token permissions are assigned to the token instead of inheriting the creating user's permissions
    • Added operation log read/write tokens scoped to one operation log and its entries
    • Added project read-only tokens scoped to selected projects or all projects the creator can access now and later
  • Service Token GraphQL Access: Added a Hasura service role for scoped service-token access
    • Project read access is backed by database views that validate the service token, service principal, creator status, and current project access
    • Service tokens can read project-related data, project-linked operation logs, evidence, reports, findings, observations, and public libraries
    • Service tokens can call selected read-oriented GraphQL Actions, including report generation, evidence and recording downloads, tag lookups, and extra field specs
  • Added service-token management to the Django admin
  • Added documentation for API tokens, service tokens, and service-principal concepts
  • Added user-session tracking for login JWTs so administrators can revoke active GraphQL sessions
  • Added a management command to clean up expired Django sessions and tracked GraphQL login sessions

Changed

  • Reworked the user profile page to organize API tokens and service tokens into clearer cards
    • API tokens are described as user-bound automation credentials
    • Service tokens are described as scoped non-human credentials
    • Expired tokens can be hidden, and that preference is remembered in local storage
    • Token expiry dates now use warning styling when expiring within seven days and expired styling after expiration
  • Added profile controls for editing API token and service token expiry dates
    • API token expiry edits now generate a replacement opaque token so the previous credential stops working immediately
  • Added service-token detail modals that show service principal, project read access, direct operation-log access, stale project grants, and token access summaries
  • Improved dark-mode styling for disabled fields
  • Made the sidebar toggle tab sticky while scrolling
  • API tokens are now opaque gwat_ credentials with hashed secrets instead of user-managed JWTs
    • Editing an API token expiry rotates the token prefix, secret hash, and UUID identifier
  • Login and collaborative editor JWTs now use explicit JWT typing
    • Login JWTs bind their jti claim to a tracked user-session identifier
    • Collaborative editor JWTs use a dedicated token type

Copilot AI review requested due to automatic review settings May 5, 2026 22:56
@augmentcode
Copy link
Copy Markdown

augmentcode Bot commented May 5, 2026

This pull request is abnormally large and would use a significant amount of tokens to review. If you still wish to review it, comment "augment review" and we will review it.

@mintlify
Copy link
Copy Markdown

mintlify Bot commented May 5, 2026

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated (UTC)
ghostwriter 🟢 Ready View Preview May 5, 2026, 10:58 PM

💡 Tip: Enable Workflows to automatically generate PRs for you.

Comment thread ghostwriter/api/models.py Fixed
Comment thread ghostwriter/api/views.py Fixed
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5073ae4324

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread ghostwriter/api/views.py Outdated
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR introduces scoped service principals/service tokens across Django and Hasura, then updates the profile/admin/docs surface so non-human automation can use fixed project/oplog permissions instead of inheriting a user's full access.

Changes:

  • Add service-principal/service-token models, migrations, forms, admin, URLs, and tests.
  • Add Hasura service role metadata and project-access view wiring for scoped reads/mutations.
  • Rework the user profile token UI and expand docs/release notes for the new token model.

Reviewed changes

Copilot reviewed 87 out of 88 changed files in this pull request and generated 11 comments.

Show a summary per file
File Description
VERSION Release version/date bump.
hasura-docker/metadata/databases/default/tables/tables.yaml Registers new service-token access view metadata.
hasura-docker/metadata/databases/default/tables/public_users_user.yaml Adds nested service read permissions for user data.
hasura-docker/metadata/databases/default/tables/public_shepherd_whoisstatus.yaml Grants service access to WHOIS status lookup data.
hasura-docker/metadata/databases/default/tables/public_shepherd_transientserver.yaml Adds project-scoped service access for transient servers.
hasura-docker/metadata/databases/default/tables/public_shepherd_staticserver.yaml Adds service access for static servers.
hasura-docker/metadata/databases/default/tables/public_shepherd_serverstatus.yaml Grants service access to server-status lookup data.
hasura-docker/metadata/databases/default/tables/public_shepherd_serverrole.yaml Grants service access to server-role lookup data.
hasura-docker/metadata/databases/default/tables/public_shepherd_serverprovider.yaml Grants service access to server-provider lookup data.
hasura-docker/metadata/databases/default/tables/public_shepherd_servernote.yaml Adds service access for server notes.
hasura-docker/metadata/databases/default/tables/public_shepherd_serverhistory.yaml Adds project-scoped service access for server checkouts.
hasura-docker/metadata/databases/default/tables/public_shepherd_history.yaml Adds project-scoped service access for domain checkouts.
hasura-docker/metadata/databases/default/tables/public_shepherd_healthstatus.yaml Grants service access to health-status lookup data.
hasura-docker/metadata/databases/default/tables/public_shepherd_domainstatus.yaml Grants service access to domain-status lookup data.
hasura-docker/metadata/databases/default/tables/public_shepherd_domainserverconnection.yaml Adds project-scoped service access for domain/server links.
hasura-docker/metadata/databases/default/tables/public_shepherd_domainnote.yaml Adds service access for domain notes.
hasura-docker/metadata/databases/default/tables/public_shepherd_domain.yaml Adds service access for domains.
hasura-docker/metadata/databases/default/tables/public_shepherd_auxserveraddress.yaml Adds service access for auxiliary server IPs.
hasura-docker/metadata/databases/default/tables/public_shepherd_activitytype.yaml Grants service access to activity-type lookup data.
hasura-docker/metadata/databases/default/tables/public_rolodex_whitecard.yaml Adds project-scoped service access for white cards.
hasura-docker/metadata/databases/default/tables/public_rolodex_projecttype.yaml Grants service access to project-type lookup data.
hasura-docker/metadata/databases/default/tables/public_rolodex_projecttarget.yaml Adds project-scoped service access for project targets.
hasura-docker/metadata/databases/default/tables/public_rolodex_projectsubtask.yaml Adds project-scoped service access for subtasks.
hasura-docker/metadata/databases/default/tables/public_rolodex_projectscope.yaml Adds project-scoped service access for scope items.
hasura-docker/metadata/databases/default/tables/public_rolodex_projectrole.yaml Exposes role position and adds service lookup access.
hasura-docker/metadata/databases/default/tables/public_rolodex_projectobjective.yaml Adds project-scoped service access for objectives.
hasura-docker/metadata/databases/default/tables/public_rolodex_projectnote.yaml Adds project-scoped service access for project notes.
hasura-docker/metadata/databases/default/tables/public_rolodex_projectcontact.yaml Adds project-scoped service access for project contacts.
hasura-docker/metadata/databases/default/tables/public_rolodex_projectassignment.yaml Adds project-scoped service access for assignments.
hasura-docker/metadata/databases/default/tables/public_rolodex_project.yaml Adds service-token relationship and project service permissions.
hasura-docker/metadata/databases/default/tables/public_rolodex_objectivestatus.yaml Grants service access to objective-status lookup data.
hasura-docker/metadata/databases/default/tables/public_rolodex_objectivepriority.yaml Grants service access to objective-priority lookup data.
hasura-docker/metadata/databases/default/tables/public_rolodex_deconflictionstatus.yaml Grants service access to deconfliction-status lookup data.
hasura-docker/metadata/databases/default/tables/public_rolodex_deconfliction.yaml Adds project-scoped service access for deconfliction entries.
hasura-docker/metadata/databases/default/tables/public_rolodex_clientnote.yaml Adds project-derived service access for client notes.
hasura-docker/metadata/databases/default/tables/public_rolodex_clientcontact.yaml Adds project-derived service access for client contacts.
hasura-docker/metadata/databases/default/tables/public_rolodex_client.yaml Adds project-derived service access for clients.
hasura-docker/metadata/databases/default/tables/public_reporting_severity.yaml Grants service access to severity lookup data.
hasura-docker/metadata/databases/default/tables/public_reporting_reporttemplate.yaml Adds service access for global/client templates.
hasura-docker/metadata/databases/default/tables/public_reporting_reportobservationlink.yaml Adds project-scoped service access for reported observations.
hasura-docker/metadata/databases/default/tables/public_reporting_reportfindinglink.yaml Adds project-scoped service access for reported findings.
hasura-docker/metadata/databases/default/tables/public_reporting_report.yaml Adds service read access and expands report update fields.
hasura-docker/metadata/databases/default/tables/public_reporting_observation.yaml Fixes user write checks and adds service library reads.
hasura-docker/metadata/databases/default/tables/public_reporting_localfindingnote.yaml Adds project-scoped service access for local finding notes.
hasura-docker/metadata/databases/default/tables/public_reporting_findingtype.yaml Grants service access to finding-type lookup data.
hasura-docker/metadata/databases/default/tables/public_reporting_findingnote.yaml Adds service access for finding-library notes.
hasura-docker/metadata/databases/default/tables/public_reporting_finding.yaml Adds service access for finding-library entries.
hasura-docker/metadata/databases/default/tables/public_reporting_evidence.yaml Adds project-scoped service access for evidence.
hasura-docker/metadata/databases/default/tables/public_reporting_doctype.yaml Expands document-type fields and adds service access.
hasura-docker/metadata/databases/default/tables/public_reporting_archive.yaml Adds project-scoped service access for archives.
hasura-docker/metadata/databases/default/tables/public_oplog_oplogentryrecording.yaml Adds service access and recording text exposure.
hasura-docker/metadata/databases/default/tables/public_oplog_oplogentryevidence.yaml Adds project-scoped service access for oplog/evidence links.
hasura-docker/metadata/databases/default/tables/public_oplog_oplogentry.yaml Adds service read/write/delete permissions for entries.
hasura-docker/metadata/databases/default/tables/public_oplog_oplog.yaml Adds service read access for oplogs.
hasura-docker/metadata/databases/default/tables/public_django_q_task.yaml Narrows task metadata exposure to manager selects.
hasura-docker/metadata/databases/default/tables/public_commandcenter_reportconfiguration.yaml Expands config fields and adds service access.
hasura-docker/metadata/databases/default/tables/public_commandcenter_extrafieldspec.yaml Expands spec fields and adds service access.
hasura-docker/metadata/databases/default/tables/public_commandcenter_extrafieldmodel.yaml Expands model metadata and adds service access.
hasura-docker/metadata/databases/default/tables/public_commandcenter_companyinformation.yaml Expands company info fields and adds service access.
hasura-docker/metadata/databases/default/tables/public_api_service_token_project_access.yaml New Hasura metadata for token/project access view.
hasura-docker/metadata/actions.yaml Enables selected actions for the service role.
hasura-docker/metadata/actions.graphql Schema file whitespace sync.
ghostwriter/users/tests/test_profile_tokens.py Adds profile token UI regression tests.
ghostwriter/users/templates/users/snippets/service_token_details_modal.html New service-token details modal UI.
ghostwriter/users/templates/users/profile.html Reworks profile layout and token management UI.
ghostwriter/templates/confirm_revoke_modal.html Generalizes revoke modal wiring for both token types.
ghostwriter/static/css/styles.css Updates disabled-field, scroll-button, and sidebar-tab styling.
ghostwriter/oplog/tests/test_views.py Hardens duplicate-evidence export test names.
ghostwriter/factories.py Adds service-principal/token/permission factories.
ghostwriter/api/urls.py Registers service-token create/revoke/expiry endpoints.
ghostwriter/api/tests/test_models.py Adds extensive API/service-token model coverage.
ghostwriter/api/tests/test_hasura_metadata.py Adds Hasura metadata contract tests for service role.
ghostwriter/api/tests/test_admin.py Adds admin revoke-action coverage for service tokens.
ghostwriter/api/templates/service_token_form.html New service-token creation form page and JS.
ghostwriter/api/models.py Implements service-principal/token models and token logic.
ghostwriter/api/migrations/0003_service_token_project_access_views.py Adds SQL views for project-read resolution.
ghostwriter/api/migrations/0002_service_tokens.py Creates service-token database schema.
ghostwriter/api/forms.py Adds token expiry/service-token forms and validation.
ghostwriter/api/admin.py Registers service-token admin models and actions.
DOCS/features/operation-logs/setting-up-automated-logging.mdx Documents automation-token guidance for oplogs.
DOCS/features/graphql-api/authentication.mdx Documents API tokens vs service tokens.
DOCS/features/access-authentication-and-session-controls/user-profile-and-tokens.mdx New profile/token management documentation page.
DOCS/features/access-authentication-and-session-controls.mdx Links the new profile/token docs page.
DOCS/docs.json Adds new docs page to navigation.
config/settings/base.py Updates application version constants.
CHANGELOG.md Adds 6.4.0 release notes.

Comment thread hasura-docker/metadata/actions.yaml
Comment thread ghostwriter/static/css/styles.css
Comment thread ghostwriter/users/templates/users/profile.html Outdated
Comment thread hasura-docker/metadata/actions.yaml
Comment thread ghostwriter/static/css/styles.css
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 98 out of 100 changed files in this pull request and generated 1 comment.

Files not reviewed (1)
  • javascript/package-lock.json: Language not supported

This prevents an admin from trying to generate a token as another user. More importantly, creation of tokens via the console do not properly generate a token that can be captured, so tokens generated here would be broken.
This restricts the collab JWTs to only being able to access the finding, report, or observation for which they were generated. This prevents the collab tokens from being taken from network traffic and then reused with the GraphQL API as a user token.
There's no reason to create a user session in the admin console.
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.

2 participants