>_ Analyst Engineering

API Keys, PATs, and OAuth Tokens: The Analyst's Guide to Credentials

Written by Ahmed at Analyst Engineering, a Senior Technical Business Analyst with 10+ years in banking and payments delivery.

Cover for a guide to API keys, personal access tokens, and OAuth tokens for technical analysts, showing an authorization header and a token lifetime.

Key takeaways

  • An API key identifies an application and usually never expires; a personal access token acts as a specific human with that person's permissions; an OAuth access token is issued per session, scoped, and short-lived. The lifetime is the security property that matters most.
  • Prefer the client credentials flow over a static API key wherever the API offers it, because a token that expires in an hour turns a leaked credential from an open door into a sixty minute window.
  • Credentials belong in environment variables or a secret manager, never in a Postman or Bruno collection, a notes vault, a Jira comment, a screenshot, or a repository, because all six of those are shared far more often than anyone plans for.
  • In payments the credential is frequently not a key at all: mutual TLS with a client certificate, message signing, or an IP allowlist, and an analyst who cannot describe which one an interface uses cannot write its non-functional requirements.

An API key identifies an application and usually never expires. A personal access token acts as a specific person with that person’s permissions. An OAuth access token is issued per session with a defined scope and a lifetime measured in minutes. The lifetime is the property that matters: a leaked static key is an open door until somebody notices, while a leaked access token is a sixty minute problem.

Every analyst working on integrations handles credentials daily, in a Postman environment, a Bruno file, a curl command, a Jira automation script, a CI pipeline. Almost nobody is taught the model behind them, so the default behaviour is to paste whatever works into whatever field accepts it and move on. That works right up until a collection with a live key is attached to a ticket, or a repository goes public with a token in a test file, and then it is an incident with your name on it.

This is also analyst work in a more formal sense. When you specify an interface, the authentication mechanism, its scopes, its rotation procedure, and its failure behaviour are requirements, and they are the ones most often left as “TBC by security” until integration testing. Getting them into the specification is the same job as reading an API contract properly, and the documentation side of it is covered in API Documentation from Scratch.

What are the credential types, and how do they differ?

TypeRepresentsLifetimeScopeTypical use
API keyAn applicationUntil revoked, often yearsCoarse, whole APISimple vendor APIs, internal tooling
Basic authA user accountUntil the password changesThe user’s permissionsLegacy internal systems
Personal access tokenA specific humanDays to a year, ideally under 90 daysThat human’s permissions, sometimes narrowedJira, Confluence, GitHub, internal APIs
OAuth access tokenA client acting in a scopeMinutes to an hourExactly the granted scopesModern APIs, machine to machine
Client certificate (mTLS)A network peerCertificate validity, months to yearsThe whole channelBank to bank, scheme connectivity

Read the table down the lifetime column. Everything else about credential security follows from how long a stolen one stays useful.

An API key is a static string sent in a header, X-API-Key: k_live_9f2.... It is convenient because there is no flow to implement and dangerous for the same reason: it does not expire, it usually cannot be narrowed, and it is regularly embedded in places that get shared. If a vendor offers only an API key, treat the key as a password.

A personal access token is the credential an analyst uses most. It represents you, carries your permissions, and can be revoked individually without disturbing your account, which is exactly why it is the right thing for automating Jira and Confluence. Its one real weakness is human: a PAT shared with a colleague, or used for a service that outlives your employment, produces an audit trail that says you did things you did not do. A PAT is personal in the way a signature is personal.

An OAuth access token is issued by a token endpoint after a client authenticates, carries a scope, and expires. The extra step is worth it because the credential you hold at rest, the client secret, is used only against the token endpoint, and the credential flying around your system all day expires by itself.

A client certificate is the one payments analysts meet that others do not, and it is covered below.

How does the client credentials flow actually work?

This is the flow behind most modern banking APIs, and it is two requests.

# 1. Exchange the client credentials for a short-lived access token
curl -s -X POST "https://auth.bank.example/oauth2/token" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -u "$CLIENT_ID:$CLIENT_SECRET" \
  -d "grant_type=client_credentials&scope=payments:write payments:read"

# {"access_token":"eyJhbGci...","token_type":"Bearer","expires_in":3600,
#  "scope":"payments:write payments:read"}

# 2. Call the API with the token
curl -s -X POST "https://api.bank.example/v1/payments" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Idempotency-Key: 4f1c8f30-2b7e-4b31-9f0a-6c8a1d55e2b1" \
  -H "Content-Type: application/json" \
  -d @payment.json

Three fields in that token response are requirements you should have specified. expires_in drives the refresh behaviour, and a client that does not refresh before expiry produces a 401 storm at exactly the wrong moment. scope is what the token may do, and it should be the narrowest set that works: a reporting integration gets payments:read and nothing else, so a compromise cannot move money. token_type tells you the header format.

In an API test suite this becomes the 00-auth request that every other request chains from, which is how the Bruno or Postman collection avoids holding a long-lived credential at all. The only stored secrets are the client id and secret, in the environment, and everything the collection carries expires within the hour.

Scope is the part analysts can most usefully influence, because it is a business decision dressed as a technical one. “Can the reconciliation service initiate a payment?” is a question with an obvious answer that nobody asks until someone reads the token scopes in production.

What does the analyst specify about authentication?

Auth requirements are non-functional requirements, and they are testable. A specification for an interface should answer all seven of these, and most first drafts answer two.

  1. Mechanism. OAuth client credentials, mTLS, API key, or a combination. Name it, and name the standard, because “OAuth” alone covers several flows with different risk profiles.
  2. Scopes and permissions. The exact list this consumer needs, and confirmation that it is the minimum. Write it as a table of scope to business capability.
  3. Credential lifetime and rotation. How long the client secret or certificate is valid, who rotates it, on what cadence, and through what request. This is the requirement that turns into a production incident when omitted.
  4. Rotation without downtime. Can the provider accept the old and new credential simultaneously during an overlap window? If not, every rotation is an outage, and it is worth raising while the API is still being designed.
  5. Failure behaviour. What the consumer does on a 401 (refresh once, then fail), on a 403 (do not retry, this is a scope problem, alert), and on a 429 (back off with the header the API returns). These are three different behaviours and teams commonly implement one.
  6. Storage. Where the credential lives: which secret manager, who has access, and how it reaches the runtime.
  7. Revocation. How to kill a credential in an incident, how fast that takes effect, and what breaks when it does.

Point 4 is the one I would put first if I could only ask one question, because it decides whether a control everyone agrees with is operationally possible. An interface whose rotation requires simultaneous coordinated deployment at two banks gets rotated approximately never, and a credential that is never rotated is the one that turns up in an old repository three years later.

What is different about payments interfaces?

In bank to bank and scheme connectivity, the credential is often not a key at all, and an analyst who has only seen bearer tokens is caught out by three things.

Mutual TLS. Both sides present a certificate, so the channel itself is authenticated before a request is made. The practical consequences are all operational: certificates expire on a date, they must be renewed and installed on both sides ahead of that date, and the failure mode is total, an interface that worked for two years stops at 00:00 on the expiry date. Certificate expiry belongs on the same risk register as a scheme deadline, and I have watched a settlement interface fail on a Monday morning for exactly this reason, with a valid certificate sitting in someone’s inbox.

Message level signing. Transport security proves who you are talking to; a signature proves who created the message and that it has not been altered. Schemes require it because the message may traverse intermediaries. For an analyst this creates test cases nobody thinks of: a valid message with an invalid signature must be rejected, and a message altered after signing must be rejected, and both are more interesting than the happy path.

Network controls. IP allowlists and dedicated connectivity mean the credential is only half the story: a correct token from an unexpected source is refused. This is the source of the classic “it works from the server but not from my laptop” confusion during testing, and it belongs in the environment documentation before the first test.

Each of these changes what a test environment needs. A payment API test suite that runs green with a bearer token against a mock proves nothing about an interface that will require a client certificate and a signed payload in production, and finding that out in system integration testing is a schedule problem. The domain context for all of this is in Break Into Banking.

Where do credentials belong in an analyst’s toolchain?

One rule covers every tool: the credential lives in the environment or a secret manager, and the tool references it by name.

# ~/.zshrc, or better, loaded from your organisation's secret manager
export JIRA_TOKEN="$(security find-generic-password -s jira-pat -w)"
export PAYMENTS_CLIENT_SECRET="$(vault kv get -field=secret payments/sit)"
import os
token = os.environ["JIRA_TOKEN"]     # fails loudly if absent
# Bruno environment: declared, never stored
vars {
  baseUrl: https://sit.payments.internal/api
}
vars:secret [
  clientSecret
]

And a .gitignore that assumes mistakes will happen:

.env
.env.*
!.env.example
*.local.bru
environments/*.local.json

Now the places credentials must never be, each of which I have seen in practice:

A committed repository. The classic, and the reason .env.example exists: the file documents which variables are needed and contains no values. Public repositories are scanned by bots within minutes.

A Postman or Bruno collection. Collections are exported, attached to tickets, and emailed to vendors during troubleshooting. A key inside one travels everywhere the collection goes.

A notes vault. An Obsidian vault is plain text, synced to git, and increasingly indexed by an AI assistant. A token in a note is a token in a search index.

A Jira or Confluence comment. “Here is the SIT key so you can test” is permanent, searchable by everyone with project access, and outlives the sprint by years.

A screenshot. Redaction that is a coloured rectangle over the top of an image is not redaction if the underlying image is intact, and a terminal screenshot showing a working curl command shows a working credential.

An AI prompt. Anything pasted into a model may be retained, and a curl command copied wholesale into a chat to ask why it returns 403 carries the header with it. Keep credentials out of every file a skill can read.

What do you do when a credential leaks?

Speed beats process, and the order matters because the first step is the only one that stops the bleeding.

Revoke first. Do not investigate, do not write it up, do not check whether anyone used it. Revoke the token or key, then continue. Every minute of investigation with a live credential is a minute of exposure, and revocation is reversible in the sense that you can always issue a new one.

Then rotate anything that shared its fate. If a .env file was committed, every value in it is compromised, not only the one you noticed.

Then assume the history is permanent. Removing a secret from a git repository in a new commit does not remove it, because it remains in the history and in every clone and fork. Rewriting history helps only if you also revoke, and revocation is what actually resolves the problem.

Then report it. Every organisation with a security function wants to know, and the ones with regulatory obligations need to know within a defined window. An analyst who reports a leaked SIT key promptly is doing the job; one who quietly rotates it and says nothing has made a decision that is not theirs to make.

Then fix the mechanism. A leaked credential is a systems finding, not a personal failing. If a key ended up in a collection, the fix is an environment variable pattern and a secret scanner in the pipeline, not a reminder to be careful.

The takeaway

Credentials differ mainly in lifetime and scope, and both are security properties an analyst can specify. An API key identifies an application and lives forever; a personal access token acts as you with your permissions and should expire within ninety days; an OAuth access token is scoped and expires within the hour, which is why the client credentials flow is worth the extra request wherever an API offers it. In payments, expect mutual TLS, message signing, and network allowlists, and treat certificate expiry as a dated risk rather than an operational detail.

Specify the mechanism, the scopes, the rotation procedure, whether rotation is possible without downtime, and the behaviour on 401, 403, and 429, because those are requirements and they are testable. Keep every credential in the environment or a secret manager, referenced by name, and out of collections, vaults, tickets, screenshots, and prompts. When one leaks, revoke before you investigate.

Start with API Documentation from Scratch for specifying an interface properly, and API Testing and QA Mastery for BAs for proving it behaves, or take the whole library in The Complete Tech BA Bundle.

Ahmed is a Senior Technical Business Analyst with 10+ years in banking and payments. He builds practical guides and tools for analysts at The Tech BA Toolkit.

Tags: API Security, Authentication, Payments, Systems Analysis, DevOps

About the author

Analyst Engineering is written by Ahmed, a Senior Technical Business Analyst with 10+ years of banking and payments delivery experience: ISO 20022 and SWIFT messaging, payments API integration, Kafka event validation, and production support. Every article comes from real delivery work, and each one is reviewed and updated as tools and standards change.

Newsletter

Subscribe

Practical, no-fluff playbooks for technical analysts who analyze, code, test, and support. New articles straight to your inbox.

No spam. Unsubscribe anytime.