@lastshotlabs/slingshot-m2m
npm install @lastshotlabs/slingshot-m2m
Functions
Section titled “Functions”createM2MClient
Section titled “createM2MClient”Create a new M2M client and return the auto-generated plaintext secret.
The secret is hashed with the caller-provided RuntimePassword before being persisted;
it is never stored in plaintext. The returned clientSecret is shown only once
and cannot be recovered later; callers must store it securely.
Remarks: The plaintext secret is generated as two UUID v4 values joined with '-': "<uuidv4>-<uuidv4>" (two crypto.randomUUID() calls concatenated). This produces a high-entropy secret. The secret is immediately hashed via the supplied RuntimePassword and only the hash is persisted; the plaintext is returned once and cannot be recovered.
async function createM2MClient(opts: { clientId: string; name: string; scopes?: string[]; adapter: AuthAdapter; password: RuntimePassword; }): Promise<Source: packages/slingshot-m2m/src/lib/m2m.ts
createM2MPlugin
Section titled “createM2MPlugin”Creates the Slingshot M2M (machine-to-machine) plugin.
Mounts an OAuth 2.0 POST /oauth/token endpoint that issues short-lived
JWTs via the client_credentials grant. Requires slingshot-auth to be
registered as a dependency and auth.m2m to be set in the auth plugin
config.
Remarks: Use requireScope() middleware to protect routes that should only be accessible with specific OAuth scopes granted to M2M clients.
function createM2MPlugin(): SlingshotPluginSource: packages/slingshot-m2m/src/plugin.ts
createM2MRouter
Section titled “createM2MRouter”Creates the Hono router that serves the M2M OAuth 2.0 token endpoint.
Mounts a single route:
POST /oauth/token—client_credentialsgrant; issues a signed JWT with the requested (or all allowed) scopes.
Rate-limited to 30 requests per minute per IP. Both application/json and
application/x-www-form-urlencoded request bodies are accepted (RFC 6749).
Remarks: This function is called internally by createM2MPlugin. You only need to call it directly when building a custom plugin that composes the M2M router manually.
function createM2MRouter(runtime: AuthRuntimeContext): voidSource: packages/slingshot-m2m/src/routes/m2m.ts
deleteM2MClient
Section titled “deleteM2MClient”Delete an M2M client by clientId.
No-op if the adapter does not support M2M client deletion or if the client does not exist.
async function deleteM2MClient(adapter: AuthAdapter, clientId: string): Promise<void>Source: packages/slingshot-m2m/src/lib/m2m.ts
getM2MClient
Section titled “getM2MClient”Look up an M2M client by clientId. Only active clients are returned.
async function getM2MClient(adapter: AuthAdapter, clientId: string,): Promise<(M2MClientRecord &Source: packages/slingshot-m2m/src/lib/m2m.ts
listM2MClients
Section titled “listM2MClients”List all M2M clients registered with the adapter.
Client secret hashes are not included in the returned records. Returns an empty array if the adapter does not support M2M client listing.
Remarks: clientSecretHash is intentionally excluded from list results. The hash is persisted internally for credential verification only and must never be exposed through list or read APIs. Secret hashes returned by getM2MClient are only available to the authentication layer for verification, not to callers of this function.
async function listM2MClients(adapter: AuthAdapter): Promise<M2MClientRecord[]>Source: packages/slingshot-m2m/src/lib/m2m.ts
requireScope
Section titled “requireScope”Hono middleware factory that enforces OAuth 2.0 scope requirements on a route.
Only machine-to-machine access tokens are eligible: the actor must have
kind: 'service-account' as resolved by the identify middleware from
slingshot-auth. The middleware then reads the scope claim from
tokenPayload. All requiredScopes must be present in the space-delimited
scope string; if any is missing the request is rejected.
Remarks: The scope claim is parsed as a space-delimited string per OAuth 2.0 RFC 6749 §3.3. Each token in the space-separated list is treated as a distinct granted scope. The token must contain all of the requiredScopes — partial matches are rejected. For example, a token with scope: "read:invoices write:invoices" satisfies requireScope('read:invoices', 'write:invoices') but not requireScope('admin').
function requireScope(...requiredScopes: string[]): MiddlewareHandler<AppEnv>Source: packages/slingshot-m2m/src/middleware/requireScope.ts
Interfaces
Section titled “Interfaces”M2MClientRecord
Section titled “M2MClientRecord”A machine-to-machine (M2M) client record used for service-to-service authentication.
M2M clients authenticate with a clientId + clientSecret and receive a short-lived
access token scoped to the declared scopes. Used by background workers, CI pipelines,
and internal services that cannot use user sessions.
Source: packages/slingshot-core/src/auth-adapter.ts