Skip to main content

Authentication

Musha has two kinds of callers: people using the app, and CI jobs uploading code. They use different credentials, and CI credentials are deliberately narrow.


CI credentials​

A CI job needs to do one thing: create a scan. Both CI credentials can call POST /v1/scans and nothing else. They can't read findings, manage keys, change settings or see billing.

CredentialUsed byLifetimeWhere it comes from
OIDC token exchange, for a cit_... tokenGitHub Actions, GitLab CI15 minutesThe job proves its identity with the platform's OIDC token. Musha checks it against the repository you connected
Project-scoped CI key msk_live_...Azure DevOps, BitbucketUp to one yearCreated by an admin in CI keys

Prefer OIDC when your CI supports it: there is no secret to leak, and the token can't be reused outside the job.

OIDC​

The job posts its platform token to POST /v1/ci/token and receives a short-lived Musha token to use as the bearer token on POST /v1/scans. The GitHub action does this for you. Musha only issues the token if the repository and, if you pinned one, the ref match what you connected in the project's Integration guide.

Project-scoped CI keys​

  1. In the app, open CI keys (admin only), or click Create CI key from a project's Integration guide.
  2. Pick the project. Every key belongs to exactly one project.
  3. Set an expiry date. It is required and can't be more than one year away.
  4. Copy the key. It is shown only once; Musha stores only a hash.

Send it as a bearer token:

Authorization: Bearer msk_live_...
PropertyValue
ScopeOne project. A scan for any other project returns 403 with code PROJECT_SCOPE_MISMATCH
Allowed callsPOST /v1/scans only
ExpiryRequired, one year at most
LimitFive active keys per project
RotationCreate the new key, update your CI secret, then revoke the old key

Store keys in your CI's secret manager, never in source code.


People​

The app signs people in with their account and uses a session for every other endpoint, such as listing scans or findings. These endpoints serve the app and are not part of the CI integration. There are no personal access tokens today.


Idempotency​

POST /v1/scans requires an Idempotency-Key header with a UUID. Sending the same key again returns the original response instead of creating a second scan, which makes retries safe.

-H "Idempotency-Key: $(uuidgen)"

A missing or malformed key returns 400.


Request correlation​

Responses include an X-Request-ID header. Include it when you contact support: it lets us find the exact request in our logs.


Errors​

StatusMeaning
400A field is missing or invalid, or the Idempotency-Key is missing
401The credential is missing, invalid, expired or revoked
402The subscription is canceled (ACCOUNT_CANCELED) or suspended (ACCOUNT_SUSPENDED)
403The credential is scoped to a different project (PROJECT_SCOPE_MISMATCH)
404The project doesn't exist in your organization
429A scan limit was reached. See Limits