Feature Description
We want to implement scoped API tokens so users are not limited to using their personal JWTs when those permissions are not required.
Are you intending to implement this feature?
Yes.
Current Behavior
API tokens are JWTs that represent their users and carry their users' permissions. There is no way to limit the scope of permissions for different jobs.
Desired Behavior
To begin, we offer the option to generate "service tokens" that have specific purposes and follow this criteria:
- Use opaque tokens instead of JWTs (easier to copy/paste and use)
- Identify the tokens with a prefix—e.g.,
gwst_
- Scoped to a specific purpose—e.g., activity logging, read-access
We expand this feature to add more options and, eventually, the option to create tokens with granular permission sets.
Use Case
A service token for mythic_sync that has read access to a specific Oplog and read/write access to that Oplog's entries. This is a much better scenario than using a user's JWT, particularly in cases where the logging utility is in a shared environment. Unless someone is working alone, this is often unavoidable because the entire team will have root access to these systems.
The above use case is the primary objective of the MVP.
Another common use case is granting access to an LLM. For most use cases, the LLM only needs read-access, and may only need read-access to a specific project. That is sufficient for an LLM that may be looking at Ghostwriter for analytics or report writing without exposing potentially dangerous write permissions.
Implementation Suggestions
Add a new non-human auth path alongside existing user JWT/API tokens:
ServicePrincipal
- A non-human actor record
- Created automatically when a user creates a new service token
- Tracks
name, service_type, created_by, and active status
ServiceToken
- Opaque credential in the form
gwst_<prefix>_<secret>
- Stores hashed secret, expiry, revocation state, last-used timestamp, creator, and owning
ServicePrincipal
ServiceTokenPermission
- Generic permission rows attached to the token
- MVP uses these to represent one scoped Oplog permission set
Hasura integration:
GraphqlAuthenticationWebhook recognizes service tokens
- For valid service tokens it returns:
X-Hasura-Role=service
X-Hasura-Service-Principal-Id=<id>
X-Hasura-Allowed-Oplog-Id=<oplog_id>
X-Hasura-Principal-Type=service
X-Hasura-User-Name=<service principal name>
- It does not return
X-Hasura-User-Id for service tokens
- Service-token auth is based only on token scope, never on the permissions of the real user who created it
Add a service role to Hasura for permission checks. We can also add a X-Hasura-Allowed-Project-Ids header for enabling project access for an LLM token. With Hasura's _in operator, we can check a list of project IDs to enable access to multiple projects.
User flow:
- Visit the user profile as you would to create an existing token
- Click Create for a new service token section
- Choose to create a new Service Principal or reuse an existing one
- Provide a name and select options
This flow enables a user to seamlessly create a new Service Principal or reuse an existing one to organize their tokens. For example:
- Service Principal: Mythic Sync
- Service Token: ACME Q2 Penetration Test
- Service Token: SpecterOps Q2 Red Team
- Service Principal: LLM
- Service Token: AWS Bedrock
- Service Token: Ghostwriter MCP
Additional Information
Some of the described implementation is somewhat overkill for the MVP. The intent is to create a foundation we can use to build out this feature depending on future demand.
Feature Description
We want to implement scoped API tokens so users are not limited to using their personal JWTs when those permissions are not required.
Are you intending to implement this feature?
Yes.
Current Behavior
API tokens are JWTs that represent their users and carry their users' permissions. There is no way to limit the scope of permissions for different jobs.
Desired Behavior
To begin, we offer the option to generate "service tokens" that have specific purposes and follow this criteria:
gwst_We expand this feature to add more options and, eventually, the option to create tokens with granular permission sets.
Use Case
A service token for
mythic_syncthat has read access to a specific Oplog and read/write access to that Oplog's entries. This is a much better scenario than using a user's JWT, particularly in cases where the logging utility is in a shared environment. Unless someone is working alone, this is often unavoidable because the entire team will have root access to these systems.The above use case is the primary objective of the MVP.
Another common use case is granting access to an LLM. For most use cases, the LLM only needs read-access, and may only need read-access to a specific project. That is sufficient for an LLM that may be looking at Ghostwriter for analytics or report writing without exposing potentially dangerous write permissions.
Implementation Suggestions
Add a new non-human auth path alongside existing user JWT/API tokens:
ServicePrincipalname,service_type,created_by, andactivestatusServiceTokengwst_<prefix>_<secret>ServicePrincipalServiceTokenPermissionHasura integration:
GraphqlAuthenticationWebhookrecognizes service tokensX-Hasura-Role=serviceX-Hasura-Service-Principal-Id=<id>X-Hasura-Allowed-Oplog-Id=<oplog_id>X-Hasura-Principal-Type=serviceX-Hasura-User-Name=<service principal name>X-Hasura-User-Idfor service tokensAdd a
servicerole to Hasura for permission checks. We can also add aX-Hasura-Allowed-Project-Idsheader for enabling project access for an LLM token. With Hasura's_inoperator, we can check a list of project IDs to enable access to multiple projects.User flow:
This flow enables a user to seamlessly create a new Service Principal or reuse an existing one to organize their tokens. For example:
Additional Information
Some of the described implementation is somewhat overkill for the MVP. The intent is to create a foundation we can use to build out this feature depending on future demand.