MagenMagen Docs
Best practices

Security

The Pix integration handles real money. Every layer must have its own line of defense.

Token storage

Bearer token is Magen's only credential. Whoever has it can move the balance.

Where to storeOK?
Google Secret ManagerYes
AWS Secrets ManagerYes
HashiCorp VaultYes
Environment variable in CIYes
.env in productionNo
Hardcoded in codeNo
localStorage / sessionStorageNo
Front-end (Web, Mobile)Never

Never expose the token on the front-end. Every Magen call must go through your backend, which injects the Authorization on the server.

Log masking

Configure your logger to mask the Authorization header and sensitive payload fields (payerDocument, pixKey, etc).

import pino from 'pino';

const logger = pino({
  redact: {
    paths: [
      'req.headers.authorization',
      'res.headers.authorization',
      '*.payerDocument',
      '*.pixKey',
    ],
    censor: '[REDACTED]',
  },
});
import logging, re

class RedactFilter(logging.Filter):
    def filter(self, record):
        if isinstance(record.msg, str):
            record.msg = re.sub(r'Bearer\s+[A-Za-z0-9._\-]+', 'Bearer [REDACTED]', record.msg)
        return True

logging.getLogger().addFilter(RedactFilter())
logger, _ := zap.NewProduction()
defer logger.Sync()

logger.Info("magen call",
    zap.String("url", url),
    zap.String("authorization", "[REDACTED]"),
)

Token rotation

When to rotateAction
Someone with access leaves the companyImmediate
Suspected leak (accidental commit, public log)Immediate + audit
Preventive rotationQuarterly or semi-annually
After pen-testImmediate if exposed during the test

Request the rotation from Magen support. Have a planned rollover (two active tokens for a window) so you don't bring production down.

Webhook endpoint protection

Only accept callbacks from Magen's official IP. Request the current IP from support.

location /webhooks/magen {
  allow 35.199.0.0/16;
  deny all;
  proxy_pass http://backend;
}

Create a WAF rule: (http.request.uri.path eq "/webhooks/magen" and ip.src ne <IP_MAGEN>) → Block.

const MAGEN_IPS = (process.env.MAGEN_WEBHOOK_IPS ?? '').split(',');

app.post('/webhooks/magen', (req, res, next) => {
  const ip = req.ip;
  if (!MAGEN_IPS.includes(ip)) return res.status(403).end();
  next();
});

DICT validation before paying

On Pix withdrawals by key, validate the holder via DICT before transferring. It detects bank/CPF changes and prevents paying the wrong recipient.

async function safeWithdraw(pixKey: string, pixType: string, expectedName: string, amount: number) {
  const url = new URL('https://api.magen.processamento.com/v1/pix/key');
  url.searchParams.set('key', pixKey);

  const dict = await fetch(url, {
    headers: {
      Authorization: `Bearer ${process.env.MAGEN_TOKEN}`,
      'Content-Type': 'application/json',
    },
  }).then(r => r.json());

  if (dict.name?.toLowerCase().trim() !== expectedName.toLowerCase().trim()) {
    throw new Error(`Holder mismatch: expected ${expectedName}, found ${dict.name}`);
  }

  return createWithdraw({ pixKey, pixType, amount });
}

Details at DICT Lookup.

2FA on sensitive operations

Consider additional 2FA in your application (not at Magen) before:

  • Withdrawal above a high limit.
  • Creating/changing a withdrawal Pix key.
  • Admin login with permission to move balance.

Magen already validates on the backend, but application-level 2FA reduces the blast radius of a compromised session. Details at 2FA.

Principle of least privilege

SetupRecommendation
Single token for prod + devSeparate: sandbox token vs prod token.
Same token shared across servicesOne token per service/team (to audit usage).
Devs with access to the prod tokenOnly infra/SRE should have it; devs use sandbox.

Common pitfalls

PitfallSymptom
Token in a versioned .envLeaks on the first wrong git push --force
Logger prints the Authorization headerToken leaks in any log capture
Webhook open to any IPForged payloads may be accepted
Paying without DICT on withdrawal by keyMay pay the wrong recipient
Same token in sandbox and productionAn environment mistake becomes a prod incident

On this page