TABLE OF CONTENTS
A Service Account gives an app or automated job its own identity in Stack Internal. Use it when software needs to call a supported API without a person signing in each time. This guide explains how to set one up, protect its credentials, and choose between machine access and access on behalf of a person.
What a service account is
A service account is a machine-to-machine connection between an external service and Stack Internal. It belongs to one workspace, has a client ID, and a set of API permissions. You then create a credential with a client secret. The client ID names the account. The secret works like a password. An access token is a short-lived pass that the app gets by sending its ID and secret to the token service. The app uses that pass to call the API, which lets software talk to Stack Internal.
The account acts as itself. It does not sign in as the admin who created it, inherit that admin’s role, or become a member of a user group or segment. API permissions control which actions it may take. Access to the underlying content can have further rules.
Why use one
- Run approved jobs without a person signing in for each run.
- Keep an integration separate from an employee’s login and personal tokens.
- Give each app only the access it needs, and change its credentials on its own.
- Track account and credential changes in audit events. Supported API actions can also identify the machine that made the request.
Recommended practice: create a separate Service Account for each app and environment. Use a clear name, such as “Nightly member sync”. This makes access reviews and credential changes easier.
How it differs from an OAuth application
Service Accounts also use OAuth. The difference is whose identity the app uses. In Stack Internal, an OAuth application normally asks a person to sign in and approve access. A Service Account uses the OAuth client credentials flow to act on its own.
| Question | Service Account | OAuth application acting for a person |
|---|---|---|
| Who acts? | The machine account. | The signed-in person. |
| How does it get a token? | Client ID and client secret. No user sign-in is needed for each token. | A user sign-in and authorization flow. |
| What limits access? | The account’s granted permissions, endpoint rules, and content access rules. | Both the app’s OAuth scopes and the person’s current permissions. |
| When should I use it? | Approved unattended jobs and server integrations. | Tools that must act as a specific person and respect that person’s access. |
An OAuth application’s client ID identifies the app; it does not, by itself, give the app an independent machine identity. These instructions cover Stack Internal. Stack Internal Community has its own authentication system.
Before you start
- Confirm that Service Accounts are enabled in the correct Organization workspace.
- Have a human admin with the service-accounts:manage permission create and manage the account. The built-in Admin role has this permission by default.
- Confirm the API or tool supports Service Accounts and identify the permissions it needs. A token alone does not grant access to every endpoint.
- Get the correct AuthKit token URL and API base URL for your environment and region from your admin or Support. Use a server or trusted job runner that can keep a secret.
Create the account and its first credential
- Open Service accounts. Open the Service accounts page for your workspace in Control Center. If there is no menu item, ask your admin or Support for the page link and confirm the feature is enabled.
- Create the account. Select Create service account. Enter a name and, if useful, a short description of the app and its owner.
- Choose permissions. Select only the API permissions the app needs. It needs at least one granted permission to pass the current token exchange checks. Select Create service account.
- Create a credential. On the account’s page, find Credentials and select Create. Creating the account itself does not create a secret.
- Save the details. Copy the Client ID and the new Secret into your approved secret store. The full secret appears only once. Select Done after you save it. If you lose it, create a new credential and revoke the lost one.
Do not put the secret in source code, a browser app, a mobile app, logs, or support tickets. Treat access tokens as secrets too. Only share masked secret endings and request IDs when troubleshooting.
Get an access token and call the API
Your app sends this form request to the correct AuthKit token endpoint. Replace the placeholders with your settings. Use HTTPS and form-encode each value. This is a request template, not a ready-to-run command.
POST https\://\<authkit-domain\>/oauth2/token
Content-Type: application/x-www-form-urlencoded
grant\_type=client\_credentials\&client\_id=\<CLIENT\_ID\>
\&client\_secret=\<CLIENT\_SECRET\>
The form body above is wrapped for display. Send it as one form body. Read access_token from the response. Use expires_in to learn when the token expires. Request a new token before that time using the same flow; this flow does not require a person to sign in again.
Send the access token in the Authorization header of a supported API request. Use the method, path, and body listed for that endpoint in the API Browser. Do not send the client secret as the bearer token.
Authorization: Bearer \<ACCESS\_TOKEN\>
Stack Internal checks the token and the account’s workspace, then checks access to the requested operation. Its gateway handles the internal token exchange. Your app does not call /auth-internal/issue-jwt directly.
For developers: the client ID is used to get tokens. The separate service account ID returned by the management API is used to manage the account. OAuth uses the wire term scope for granted access; this is different from a Stack Internal knowledge Scope.
Manage access and credentials
From the account list, choose Manage account & credentials. You can edit the name, description, or permissions and select Save changes. The Credentials section shows each secret’s masked ending, creation date, and last-used date.
To rotate a secret, create a second credential. Update the app’s secret store, obtain a new token, and test an approved API call. Once the app uses the new credential, revoke the old one. This order helps avoid a break in service.
Revoke removes one credential. The account and its other credentials remain. Delete service account removes the account and blocks new token exchanges. Both actions require confirmation and cannot be undone.
Access may not stop at once. Permission changes and credential revocation can leave already-issued tokens usable until they expire. Deleting the account blocks new exchanges, but an internal token already issued may remain valid until its expiry. The internal token lifetime defaults to five minutes; this is separate from the access token’s expires_in value. Contact Support if you need urgent access containment.
Limits to keep in mind
- One workspace per account. It cannot gain access to another workspace by changing a URL or request value.
- No user impersonation. It cannot inherit an employee’s roles, groups, or access to private source content. Content access rules still apply.
- Some actions require a person. Service Account management and signed-in user profile operations reject machine identities. Adding a permission cannot bypass that rule.
- Support varies by endpoint and tool. Confirm each API, Chat workflow, or MCP tool before use. Do not assume that all tools accept machine access just because token creation works.
- Secrets cannot be viewed again. A credential limit may also prevent creation of another secret. Remove an unused credential only after checking which app uses it.
- API permissions do not remove product limits. Check the endpoint’s current documentation for request limits and any workspace usage limits. This guide does not set a fixed quota.
- These credentials are for Stack Internal. They do not replace Google, Slack, or other connector credentials, or grant access to those external systems.
If something goes wrong
| Problem | What to check |
|---|---|
| Service accounts is missing | Confirm the workspace plan, feature availability, page link, and your management permission. |
| Token request fails | Check the AuthKit domain, client ID, secret, and whether the credential was revoked. |
| API returns 401 or 403 | Get a fresh token. Check the API host, account status, assigned permissions, and whether the endpoint requires a person. |
| Search returns no expected content | Check the endpoint and source content access rules. A valid token does not prove access to a document. |
| You lost the secret | Create a replacement and update the app. The old secret cannot be recovered. |
When you contact Support, include the workspace, environment, client ID, API operation, time of the failure, status code, and request or trace ID. Do not include secrets or bearer tokens.