Skip to main content
All articles
Compliance5 min read

Protecting your API keys

Protecting your payment API keys: five simple rules, planned rotation, and what to do, in order, when a key has already leaked into a repository.

Your API key authorises everything its permissions cover: creating payment links, reading your transactions, issuing refunds. There is no second factor and no confirmation — so grant each key only the permissions it actually needs. It is a secret in the full sense of the word.

The five rules

A key lives on a server, never in a browser. Not in client-side JavaScript, not in a mobile app — an .apk file decompiles in seconds. If your front end needs to trigger a payment, it calls *your* backend, which calls ours. The full architecture for iOS and Android is described in payments in a mobile app.

A key lives in an environment variable or a vault, never in code. Not even in a private repository: repositories change status, collaborators change employers, backups get copied.

A test key and a production key are two different things. The prefix says so — chari_sk_test_ versus chari_sk_live_ — and the environment is determined by the key itself. That is precisely what makes it impossible to send a test call to production by mistake. The Authentication guide in the API docs covers the header and the exception for the /checkout/* endpoints. The test key, for its part, is yours without waiting: Start in test mode opens the sandbox as soon as you sign up, and you create the key yourself from the portal.

A key does not get written to a log. Beware of error trackers and observability tools that capture HTTP headers: that is the most common leak, and the quietest, because the secret ends up with a third party without anyone ever deciding it should.

A key is not shared over messaging. Not by email, not on Slack, not on WhatsApp. Those channels retain, index and back up.

What actually happens

The scenario we see most is not an attack. It is a developer in a hurry who puts the key in a config file "just to test", forgets, and pushes. The repository is private, so "it's fine". Six months later it goes public, or a contractor gets access, or a backup lands somewhere else.

The second most common scenario is the .env file committed on day one of the project, before anyone had written the .gitignore. The other attacks aimed at merchants — fake screenshots, fake receipts, stolen access — are covered in online payment fraud.

If a key has leaked

In order, and without waiting:

  1. 1Revoke it. A compromised key is not a key to watch, it is a key to delete. Create its replacement first if you want to avoid an outage, but do not delay the revocation.
  2. 2Treat the whole history as exposed. Removing the file from the repository is not enough: it stays in the git history, and history gets cloned.
  3. 3Look at what was done with it. The operations log tells you what was created, read and refunded, and when.
  4. 4Fix the cause. A .gitignore, a secret scan on commit, a vault — otherwise it will happen again.

Planned rotation

Rotating a key should never be an event — it is maintenance. A key that has never been rotated is a key nobody knows how to rotate, and that skill always gets discovered at the worst moment: during a leak.

The move is simple because two keys can coexist during the switch: create the new one, deploy it, check that traffic flows, revoke the old one. No interruption. Do it once without urgency, write down the procedure — which secret, in which manager, deployed how — and put a date in the calendar. Twice a year is enough; what matters is not the frequency but that the muscle exists.

Rotation also forces a useful discovery: the real list of places the key lives. If the switch breaks a service nobody remembered, you have just learned something that would have cost far more during an incident.

Keys in a team

With two developers, the key gets passed from hand to hand. With ten, it ends up in a Slack channel, a wiki, a "temporary" file — and each of those places is a leak in the making.

Three rules hold a team together:

  • One source of truth: the secrets manager. A key circulating anywhere else is considered compromised, on principle.
  • CI gets its own key. Continuous-integration tests run on the sandbox, with a dedicated key that rotation can sacrifice without touching production. It is the same logic as keeping sandbox and production separate for good.
  • A member leaving triggers a rotation. Not out of distrust — because a returned workstation, a personal laptop, an individual password manager are all places you no longer control.

And one habit that costs nothing: production keys are never displayed on screen in full. The portal truncates them after creation; your internal tools should do the same.

The right reflex at the start

Before your very first call, add .env and .env.local to your .gitignore, and check that neither is already tracked by git. It is thirty seconds at the start of a project, and it avoids the one category of security incident that is both mundane and expensive.

Creating a key is itself protected: the portal requires re-authentication before every sensitive action — the strong authentication described on the security page. It shows a key exactly once, at creation — in a modal that will not close until you have copied it — and never sends it by email or displays it again, including to you. That constraint is deliberate: a key you can re-read is a key you will eventually re-read somewhere you do not control.

Next step

The right time to set these rules is before your first production key. Start in test mode asks for a name, a work email and your company name, then a password chosen from the activation link sent by email; you then create your test key from the portal and put it straight into your vault — free, with no time limit. The payment API in Morocco guide takes the integration from there.

Written by ChariPay team.

Read next

Guide4 min read

Sandbox to production: the go-live list

Moving from sandbox to production: the checklist before you switch keys — signed webhooks, idempotency, secrets, the classic oversights.

Technical5 min read

Getting your webhook integration right

Getting your webhook integration right: the five mistakes found in almost every integration, and the fifteen-line handler that avoids all of them.

Ready to try it yourself?

Create your account and take test-mode payments today: it is free, with no approval to wait for. A question? Our team supports merchants and developers alike.

  • Free, no commitment
  • Test mode from sign-up
  • No approval to wait for