DEV Community

Cover image for A note on scoping service accounts: they’re not people
Saif
Saif

Posted on

A note on scoping service accounts: they’re not people

If you’ve built anything that involves agents, bots, integrations, or background tasks, there’s a good chance you’ve reached for an API key tied to a user.

It works.

But it also introduces real security risks and long-term maintainability problems.

Service accounts aren’t people. They shouldn’t inherit the privileges of users or operate on behalf of them. Instead, they should be created and controlled by the organization, with clearly defined and scoped permissions.

What are service accounts?

Service accounts are non-human identities created for programmatic access to your system.

In SaaS platforms, these are often used to:

  • Authenticate AI agents running internal automations
  • Allow third-party integrations like Zapier or ERP systems to fetch or sync data
  • Power scheduled jobs like a nightly invoice sync or analytics export
  • Securely access internal APIs without relying on long-lived user tokens

These service accounts act on behalf of the organization, not a person.

A well-structured service account:

  • Is owned by an organization, not a user
  • Has a clear, limited set of scopes describing what it can do
  • Uses credentials like client_id and client_secret, not passwords
  • Can be issued, rotated, and revoked by the organization itself

This is critical for securing AI agents, background jobs, data sync tools, and more. And when done right, it leads to far safer automation and easier lifecycle management.

Configure scopes properly

When you register a service account, one of the most important things you can do is define the correct scopes right away.

Here’s how you do that in practice:

curl -L 'https://<SCALEKIT_ENVIRONMENT_URL>/api/v1/organizations/<ORGANIZATION_ID>/clients' \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer <SCALEKIT_ACCESS_TOKEN>' \
-d '{
    "name": "billing-job",
    "description": "Nightly sync of invoices to ERP",
    "scopes": [
        "billing.read"
    ],
    "audience": [
        "billing-api.yourapp.com"
    ],
    "expiry": 3600
}'
Enter fullscreen mode Exit fullscreen mode

💡

I’m using Scalekit to simplify the whole process.

Let’s break down the code:

  • scopes: This defines exactly what the client can access. You pass this during registration, there’s no separate /scopes management endpoint. If a client doesn’t need access to billing:write, for example, don’t give it.
  • audience: Optional but highly recommended. This limits the token’s validity to a specific API or domain.
  • expiry: How long the token remains valid. Defaults to one hour (3600 seconds), which is a good security baseline.
  • No broad admin scopes. Only what’s necessary for the task, nothing more. This follows the Principle of Least Privilege and reduces your attack surface.

Issue and manage tokens

Once the scopes are configured, API clients can mint a token for the service account to authenticate.

curl -X POST \
  "https://<YOURAPP_SCALEKIT_ENVIRONMENT_URL>/oauth/token" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=client_credentials" \
  -d "client_id=<YOURAPP_CLIENT_ID>" \
  -d "client_secret=<YOURAPP_CLIENT_SECRET>" \
  -d "scope=openid profile email"
Enter fullscreen mode Exit fullscreen mode

You will get a response like so:

{
  "access_token": "<YOURAPP_ACCESS_TOKEN>",
  "token_type": "Bearer",
  "expires_in": 3600,
  "scope": "openid"
}
Enter fullscreen mode Exit fullscreen mode

The service now has a valid bearer token that it can use to access authorized resources.

Want the full picture?

In this post, we focused on how to configure scopes and permissions properly.

If you'd like to go deeper:

  • How to create organization-level service accounts
  • Validate, rotate, and revoke tokens
  • Design a secure token lifecycle for automation

Read the full guide on implementing organization-scoped service accounts.

It’s your blueprint for building a service account model that works across agents, integrations, and secure internal systems.

Your turn

How are you scoping your service accounts today?

  • Do you define scopes at registration?
  • Are your clients locked to specific audiences?
  • Are you still using user-bound tokens?

If you’ve got some best practices, drop them below 👇

Top comments (0)