npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

haraka-plugin-vault-enhanced-dkim

v1.0.4

Published

Haraka plugin that enhances DKIM signing and verification with Vault integration

Readme

haraka-plugin-vault-enhanced-dkim

A Haraka plugin that integrates with HashiCorp Vault to securely manage DKIM signing keys for multiple domains.

Overview

This plugin implements the DKIM Core specification with enhanced security by storing DKIM keys in HashiCorp Vault instead of the filesystem.

Key Features

  • Centralized DKIM key management using HashiCorp Vault
  • Automatic key retrieval for multiple domains
  • Secure key storage with audit trails
  • No local key files required

Install

cd /path/to/local/haraka
npm install @brassnode/haraka-plugin-vault-enhanced-dkim
echo "vault-enhanced-dkim" >> config/plugins
service haraka restart

Vault Configuration

Prerequisites

  1. HashiCorp Vault server installed and configured
  2. KV v2 secrets engine enabled
  3. Appropriate Vault authentication configured

Key Storage Structure

DKIM keys are stored in Vault under the following path structure:

dkim/{domain-name}

Each domain's secret should contain the following keys:

{
  "selector": "your-selector",
  "private_key": "-----BEGIN RSA PRIVATE KEY-----\n...",
  "public_key": "-----BEGIN PUBLIC KEY-----\n...",
  "domain": "example.com",
  "created_at": "2024-01-01T00:00:00.000Z"
}

Vault Permissions

The Vault token/role used by this plugin needs the following capabilities:

path "kv/data/dkim/*" {
  capabilities=["read"]
}

path "kv/metadata/dkim/*" {
  capabilities=["read", "list"]
}

Generating and Storing Keys

This plugin includes a key generation script that creates DKIM keys and stores them directly in Vault or in the local filesystem:

Set Vault environment variables (if using vault storage)

export VAULT_ADDR="http://vault.example.com:8200"
export VAULT_TOKEN="your-vault-token"

Usage:

./config/dkim/dkim_key_gen.sh <domain> [--store vault|local] [--path path_prefix]

Arguments:
  DOMAIN               Domain name to generate DKIM keys for (required)
  --store vault|local  Storage mode for the generated keys (default: vault)
  --path path_prefix   Optional path prefix:
                      - For vault: Path prefix in Vault (default: dkim)
                      - For local: Directory path (default: ./config/dkim)

Examples:

# Generate and store in Vault (default path: ./config/dkim)
./config/dkim/dkim_key_gen.sh example.com

# Generate and store in local filesystem with default path (./config/dkim)
./config/dkim/dkim_key_gen.sh example.com --store local

# Generate and store in Vault with  with default path (dkim/example.com)
./config/dkim/dkim_key_gen.sh example.com --store vault

# Generate and store in local filesystem with custom path (custom/local/path)
./config/dkim/dkim_key_gen.sh example.com --store local --path /custom/local/path

# Generate and store in Vault with custom path (custom/path/example.com)
./config/dkim/dkim_key_gen.sh example.com --store vault --path custom/path

The script will:

  1. Generate a 2048-bit RSA key pair
  2. Create a selector in the format mmmYYYY (e.g., jan2024)
  3. Store the keys in Vault at dkim/example.com or in the local filesystem at ./config/dkim/example.com (or custom paths if specified)
  4. Display DNS configuration instructions

Plugin Configuration

dkim.ini

; The key store to use: 'local' or 'vault'
; 'local' - keys are stored in the file system under /config/dkim-keys
; 'vault' - keys are stored in HashiCorp Vault
[main]
key_store=local

[vault]
addr=http://vault.example.com:8200
token=your-vault-token
timeout=5000

[redis]
host=127.0.0.1
port=6379
password=
db=0
cache_ttl=3600
; Encryption key for caching private keys in Redis (optional)
; If set, private keys will be encrypted before being stored in Redis
; and decrypted when retrieved. Use a strong, random key.
; Example: cache_encryption_key=your-32-character-random-string
; Leave empty to disable encryption
;
; Generate a secure encryption key using either:
; openssl rand -hex 32
; or
; head -c 32 /dev/urandom | xxd -p -c 32
cache_encryption_key=

[sign]
enabled=false
selector=mail
domain=example.com
headers=From, Sender, Reply-To, Subject, Date, Message-ID, To, Cc, MIME-Version

[verify]
enabled=true
allowed_time_skew=60
sigerror_log_level=info

Main Configuration Notes

  • key_store: Specifies where DKIM keys are stored and retrieved from. Options are 'vault' (recommended) for HashiCorp Vault storage or 'local' for filesystem storage.

Vault Configuration Notes

  • addr: Your Vault server address (e.g., http://vault:8200 or https://vault.example.com:8200)
  • token: Vault authentication token (can also be set via VAULT_TOKEN environment variable)
  • timeout: Connection timeout for Vault requests (milliseconds)

Redis Cache Configuration Notes

  • host: Redis server hostname (default: 127.0.0.1)
  • port: Redis server port (default: 6379)
  • password: Redis password (if required)
  • db: Redis database number (default: 0)
  • cache_ttl: Time-to-live for cached DKIM keys in seconds (default: 3600)
  • cache_encryption_key: Encryption key for caching private keys in Redis (optional)

Sign Configuration Notes

  • enabled: Set to true to enable DKIM signing
  • selector: Fallback selector if domain not found in Vault
  • domain: Fallback domain if not determined from message
  • headers: List of headers to include in DKIM signature. The From header is always included

Verify Configuration Notes

  • enabled: Set to true to verify incoming DKIM signatures
  • allowed_time_skew: Tolerance for timestamp differences (seconds). Useful when clock is skewed
  • sigerror_log_level: Logging level for signature errors (debug, info, warn, error)

DNS Configuration

For each domain stored in Vault, you need to publish the public key in DNS:

{selector}._domainkey.{domain}. IN TXT "v=DKIM1; k=rsa; p={public_key_base64}"

Example:

202401._domainkey.example.com. IN TXT "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQ..."

Signing Behavior

  1. When an email is received, the plugin extracts the sender's domain
  2. It queries Vault for DKIM keys at dkim/{domain}
  3. If keys are found, the message is signed with the domain's DKIM key
  4. If no keys are found, the message is not signed (or uses a default if configured)

Verification Behaviour

Verify DKIM signatures as defined by RFC 6376 and add an Authentication-Results header as appropriate.

When verification is enabled, the plugin:

  1. Extracts DKIM-Signature headers from incoming messages
  2. Retrieves the public key from DNS using the selector and domain specified in the signature
  3. Validates the signature against the message body and signed headers
  4. Adds Authentication-Results header with the verification result

Authentication-Results Header Format

The plugin adds headers in the following format:

Authentication-Results: mail.example.com;
  dkim=pass (2048-bit key) header.d=sender.com [email protected] header.b="signature_fragment"

Possible results:

  • pass: Signature validated successfully
  • fail: Signature validation failed
  • neutral: Unable to verify (e.g., DNS lookup failed)
  • temperror: Temporary failure during verification
  • permerror: Permanent error in signature or key format

Verification Process Details

  1. Header Canonicalization: Headers are normalized according to the canonicalization method specified in the signature (simple or relaxed)
  2. Body Hash Verification: The body hash in the signature is compared against a computed hash of the message body
  3. Signature Validation: The signature is validated using the public key retrieved from DNS
  4. Time Skew Handling: Signatures are accepted within the configured allowed_time_skew to handle clock differences

Migration from Standard DKIM Plugin

To migrate from the standard haraka-plugin-dkim:

  1. Extract your existing DKIM keys from the filesystem
  2. Store them in Vault using the structure shown above
  3. Update your Haraka configuration to use vault-enhanced-dkim
  4. Remove the old dkim plugin and configuration files

Testing

This plugin provides a command-line test tool that can be used to debug DKIM issues or to check results.

# dkimverify < message
identity="@gmail.com" domain="gmail.com" result=pass

You can add --debug to the option arguments to see a full trace of the processing.

Troubleshooting

Common Issues

  1. Vault connection errors: Check your Vault address and network connectivity
  2. Authentication failures: Verify your token/credentials are valid
  3. Key not found: Ensure the domain exists in Vault at the correct path
  4. DNS verification failures: Verify your DNS TXT record matches the public key in Vault

Verify Vault Connectivity

# List all domains with DKIM keys
vault kv list dkim

# View keys for a specific domain
vault kv get dkim/example.com

Notes

This plugin and underlying library do not currently support DKIM body length limits (l=).

Contributing

Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are greatly appreciated.

If you have a suggestion that would make this better, please fork the repo and create a pull request. You can also simply open an issue with the tag "enhancement".

Top contributors

Contributors

License

Distributed under the Unlicense License. See LICENSE for more information.

Contact

Abdulmatin Sanni - @abdulmatinsanni - [email protected]