AutomationFlowsGeneral › Secrets Registry Verify

Secrets Registry Verify

Secrets Registry Verify. Webhook trigger; 7 nodes.

Webhook trigger★★★★☆ complexity7 nodes
General Trigger: Webhook Nodes: 7 Complexity: ★★★★☆ Added:

This workflow corresponds to n8n.io template #secrets-registry-verify-v1 — we link there as the canonical source.

The workflow JSON

Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →

Download .json
{
  "name": "Secrets Registry Verify",
  "nodes": [
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "secrets-registry-verify",
        "options": {
          "rawBody": false
        },
        "authentication": "headerAuth",
        "responseMode": "lastNode"
      },
      "id": "webhook-trigger",
      "name": "Webhook Trigger",
      "type": "n8n-nodes-base.webhook",
      "position": [
        200,
        300
      ],
      "typeVersion": 2
    },
    {
      "parameters": {},
      "id": "manual-trigger",
      "name": "Manual Trigger",
      "type": "n8n-nodes-base.manualTrigger",
      "position": [
        200,
        500
      ],
      "typeVersion": 1
    },
    {
      "parameters": {
        "jsCode": "// Load manifest (inline; sync with n8n/secrets.manifest.yml). Validate schema.\nconst manifest = {\n  version: '1.0',\n  secrets: [\n    { name: 'N8N_API_KEY', source: 'ENV', required: true },\n    { name: 'N8N_ENCRYPTION_KEY', source: 'ENV', required: true },\n    { name: 'SUPABASE_SERVICE_ROLE_KEY', source: 'ENV', required: true },\n    { name: 'ANTHROPIC_API_KEY', source: 'ENV', required: true },\n    { name: 'OPENAI_API_KEY', source: 'ENV', required: true },\n    { name: 'MONDAY_API_TOKEN', source: 'ENV', required: false },\n    { name: 'CLOUDFLARE_API_TOKEN', source: 'ENV', required: false },\n    { name: 'COMMANDER_WEBHOOK_TOKEN', source: 'ENV', required: true },\n    { name: 'VAULT_MASTER_KEY', source: 'ENV', required: false },\n    { name: 'FIRECRAWL_API_KEY', source: 'ENV', required: false },\n    { name: 'GRAFANA_PASSWORD', source: 'ENV', required: false }\n  ],\n  n8n_credentials: [\n    { type: 'supabaseApi', name: 'Prod - Supabase Service Role' },\n    { type: 'anthropicApi', name: 'Prod - Anthropic Claude' },\n    { type: 'anthropicApi', name: 'AnthropicApi' },\n    { type: 'openAiApi', name: 'Prod - OpenAI' },\n    { type: 'gmailOAuth2', name: 'Prod - Gmail' },\n    { type: 'googleSheetsOAuth2Api', name: 'Prod - Google Sheets' },\n    { type: 'mondayComApi', name: 'Prod - Monday.com' }\n  ]\n};\nconst schemaOk = manifest.version && Array.isArray(manifest.secrets) && manifest.secrets.every(s => s.name && s.source && s.required !== undefined);\nif (!schemaOk) throw new Error('Manifest schema invalid');\nreturn [{ json: manifest }];"
      },
      "id": "load-manifest",
      "name": "Load Manifest",
      "type": "n8n-nodes-base.code",
      "position": [
        480,
        400
      ],
      "typeVersion": 2
    },
    {
      "parameters": {
        "jsCode": "// Check ENV secrets by inspecting process.env.\n// NEVER output actual values \u2014 only presence.\nconst manifest = $input.first().json;\nconst results = { ok: true, missing: [], present: [], warnings: [] };\n\nfor (const secret of manifest.secrets) {\n  if (secret.source === 'ENV') {\n    const val = process.env[secret.name];\n    if (!val || val.startsWith('paste-your-')) {\n      if (secret.required) {\n        results.missing.push(secret.name);\n        results.ok = false;\n      } else {\n        results.warnings.push(`${secret.name} (optional) not set`);\n      }\n    } else {\n      results.present.push(secret.name);\n    }\n  }\n}\n\nresults.env_checked = manifest.secrets.filter(s => s.source === 'ENV').length;\nreturn [{ json: results }];"
      },
      "id": "check-env-secrets",
      "name": "Check ENV Secrets",
      "type": "n8n-nodes-base.code",
      "position": [
        720,
        300
      ],
      "typeVersion": 2
    },
    {
      "parameters": {
        "jsCode": "// Check VAULT_REF secrets via vault adapter (existence only).\nconst vaultBase = process.env.VAULT_BASE_URL || 'http://localhost:4000';\nconst envResults = $input.first().json;\nconst manifest = $('Load Manifest').first().json;\nconst vaultNames = (manifest.secrets || []).filter(s => s.source === 'VAULT_REF').map(s => s.name);\nif (vaultNames.length === 0) vaultNames.push('VAULT_MASTER_KEY');\nconst vaultResults = { vault_checked: 0, vault_present: [], vault_missing: [] };\nfor (const name of vaultNames) {\n  if (envResults.present && envResults.present.includes(name)) continue;\n  try {\n    const resp = await fetch(`${vaultBase}/secret/${name}`);\n    vaultResults.vault_checked++;\n    if (resp.ok) vaultResults.vault_present.push(name);\n    else vaultResults.vault_missing.push(name);\n  } catch (e) {\n    vaultResults.vault_missing.push(name);\n    envResults.warnings = envResults.warnings || [];\n    envResults.warnings.push(`Vault unreachable for ${name}: ${e.message}`);\n  }\n}\nreturn [{ json: { ...envResults, ...vaultResults } }];"
      },
      "id": "check-vault-secrets",
      "name": "Check Vault Secrets",
      "type": "n8n-nodes-base.code",
      "position": [
        960,
        300
      ],
      "typeVersion": 2
    },
    {
      "parameters": {
        "jsCode": "// Check n8n credentials via the n8n API (existence only, names only).\nconst report = $input.first().json;\nconst manifest = $('Load Manifest').first().json;\nconst n8nBase = (process.env.N8N_BASE_URL || process.env.N8N_URL || '').replace(/\\/$/, '');\nconst n8nApiKey = process.env.N8N_API_KEY;\nconst credResults = { creds_checked: 0, creds_present: [], creds_missing: [] };\nconst credList = manifest.n8n_credentials || [];\n\nif (n8nBase && n8nApiKey) {\n  try {\n    const resp = await fetch(`${n8nBase}/api/v1/credentials`, {\n      headers: { 'X-N8N-API-KEY': n8nApiKey, 'Accept': 'application/json' }\n    });\n    if (resp.ok) {\n      const data = await resp.json();\n      const existingNames = (data.data || []).map(c => c.name);\n      for (const cred of credList) {\n        credResults.creds_checked++;\n        if (existingNames.includes(cred.name)) {\n          credResults.creds_present.push(cred.name);\n        } else {\n          credResults.creds_missing.push(cred.name);\n        }\n      }\n    } else {\n      report.warnings.push(`n8n API returned ${resp.status}`);\n    }\n  } catch (e) {\n    report.warnings.push(`n8n API unreachable: ${e.message}`);\n  }\n} else {\n  report.warnings.push('N8N_BASE_URL or N8N_API_KEY not set \u2014 skipping credential check');\n}\n\nif (credResults.creds_missing.length > 0) report.ok = false;\n\nreturn [{ json: { ...report, ...credResults } }];"
      },
      "id": "check-n8n-creds",
      "name": "Check n8n Credentials",
      "type": "n8n-nodes-base.code",
      "position": [
        1200,
        300
      ],
      "typeVersion": 2
    },
    {
      "parameters": {
        "jsCode": "// Build final report. Never include secret values. Gate 4: ok, missing[], warnings[], checked_at, version_sha.\nconst r = $input.first().json;\nconst manifest = $('Load Manifest').first().json;\nconst allMissing = [...(r.missing || []), ...(r.vault_missing || []), ...(r.creds_missing || [])];\nconst report = {\n  ok: r.ok,\n  missing: allMissing,\n  warnings: r.warnings || [],\n  checked_at: new Date().toISOString(),\n  version_sha: manifest.version || '1.0',\n  summary: r.ok ? 'All required secrets and credentials are present.' : 'Missing secrets or credentials detected.',\n  env: { checked: r.env_checked || 0, present: r.present || [], missing: r.missing || [] },\n  vault: { checked: r.vault_checked || 0, present: r.vault_present || [], missing: r.vault_missing || [] },\n  n8n_credentials: { checked: r.creds_checked || 0, present: r.creds_present || [], missing: r.creds_missing || [] },\n  all_missing: allMissing\n};\nreturn [{ json: report }];"
      },
      "id": "build-report",
      "name": "Build Report",
      "type": "n8n-nodes-base.code",
      "position": [
        1440,
        300
      ],
      "typeVersion": 2
    }
  ],
  "connections": {
    "Webhook Trigger": {
      "main": [
        [
          {
            "node": "Load Manifest",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Manual Trigger": {
      "main": [
        [
          {
            "node": "Load Manifest",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Load Manifest": {
      "main": [
        [
          {
            "node": "Check ENV Secrets",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check ENV Secrets": {
      "main": [
        [
          {
            "node": "Check Vault Secrets",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check Vault Secrets": {
      "main": [
        [
          {
            "node": "Check n8n Credentials",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check n8n Credentials": {
      "main": [
        [
          {
            "node": "Build Report",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "meta": {
    "templateId": "secrets-registry-verify-v1",
    "description": "Validates all secrets from the manifest against ENV, Vault adapter, and n8n Credentials API. Returns a report with missing/present status. Never outputs secret values."
  },
  "tags": [
    "secrets",
    "self-healing",
    "infrastructure"
  ]
}
Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

Secrets Registry Verify. Webhook trigger; 7 nodes.

Source: https://github.com/jowikroon/hans-crafted-stories/blob/main/apps/personal/n8n/workflows/secrets_registry_verify.json — original creator credit. Request a take-down →

More General workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

General

A production-ready authentication workflow implementing secure user registration, login, token verification, and refresh token mechanisms. Perfect for adding authentication to any application without

Crypto, Data Table, Execute Workflow Trigger
General

Portfolio Orchestrator. Uses httpRequest. Webhook trigger; 59 nodes.

HTTP Request
General

This n8n template demonstrates how a simple Multi-Layer Perceptron (MLP) neural network can predict housing prices. The prediction is based on four key features, processed through a three-layer model.

General

github code Try yourself

Google Calendar
General

This workflow receives new consult bookings via webhook (Calendly v2 or a generic scheduling tool), generates timed confirmation and reminder messages, runs each SMS through a separate compliance work

Twilio, Email Send