Tips > Ops & Security

Audit Credential Usage Across Workflows

Over time, credentials accumulate and it becomes unclear which workflows use which credentials, whether any credentials are orphaned, and whether deprecated ...

Over time, credentials accumulate and it becomes unclear which workflows use which credentials, whether any credentials are orphaned, and whether deprecated API keys are still in use. Regular audits prevent stale credentials from becoming security liabilities.

Real-world example: An employee leaves the company. Their personal API keys are still stored as n8n credentials and used in 12 production workflows. Without an audit, the keys are never rotated and remain valid indefinitely.

Use the n8n API to audit credential usage programmatically:

// Code node: Audit credential usage
// Mode: Run Once for All Items
// Requires: n8n API access (set N8N_PUBLIC_API_ENABLED=true)

const n8nApiUrl = 'http://localhost:5678/api/v1';
const apiKey = $input.first().json.n8nApiKey; // n8n API key

// Fetch all credentials
const credentials = await this.helpers.httpRequest({
  method: 'GET',
  url: `${n8nApiUrl}/credentials`,
  headers: { 'X-N8N-API-KEY': apiKey },
});

// Fetch all workflows
const workflows = await this.helpers.httpRequest({
  method: 'GET',
  url: `${n8nApiUrl}/workflows`,
  headers: { 'X-N8N-API-KEY': apiKey },
});

// Build usage map
const credentialUsage = {};
for (const cred of credentials.data) {
  credentialUsage[cred.id] = {
    name: cred.name,
    type: cred.type,
    createdAt: cred.createdAt,
    updatedAt: cred.updatedAt,
    usedInWorkflows: [],
  };
}

for (const wf of workflows.data) {
  const nodes = wf.nodes || [];
  for (const node of nodes) {
    const creds = node.credentials || {};
    for (const [type, credRef] of Object.entries(creds)) {
      const credId = credRef.id;
      if (credentialUsage[credId]) {
        credentialUsage[credId].usedInWorkflows.push({
          workflowId: wf.id,
          workflowName: wf.name,
          nodeName: node.name,
          nodeType: node.type,
          isActive: wf.active,
        });
      }
    }
  }
}

// Identify orphaned credentials (not used in any workflow)
const orphaned = Object.values(credentialUsage).filter(
  c => c.usedInWorkflows.length === 0
);

return [
  { json: { type: 'summary', totalCredentials: credentials.data.length, orphanedCount: orphaned.length } },
  ...orphaned.map(c => ({ json: { type: 'orphaned', ...c } })),
];
```text
Schedule this audit workflow to run weekly and send the results to Slack or email. Delete or rotate orphaned credentials promptly.

**Related:** [Use Docker Compose with Health Checks for n8n and PostgreSQL](../self-hosting-operations/01-use-docker-compose-with-health-checks-for-n8n-and-postgresql.md) | [Use Path Parameters in Webhook URLs for Dynamic Routing](../webhook-mastery/01-use-path-parameters-in-webhook-urls-for-dynamic-routing.md)

Showcase builds

19 complete workflows from my own projects, each with its n8n workflow JSON to import. Showcase entries link the file at the end of the article.

See the showcase builds

Keep reading

191 entries grouped by topic, from first workflow to queue mode. Free, no signup.

Browse the encyclopedia

Need it built?

I design, build and run n8n systems for clients. Every engagement starts with a $1,500 diagnostic audit, credited toward the build.

Book a 20-minute call