PHP SDK for the Venmail Verification Standard (VVS-1) — cryptographic agent identity and message integrity for email.
VVS-1 adds Ed25519-signed, verifiable agent identity to email as an application-layer convention. It enables AI agents, automated services, and cross-organization systems to prove who sent a message and that it hasn't been tampered with.
composer require venmail/vvsRequires PHP 8.1+ with the sodium extension (built-in since PHP 7.2).
use Venmail\VVS\KeyGenerator;
use Venmail\VVS\Signer;
// Generate keypair (once — store the private key securely)
$keyPair = KeyGenerator::generate();
// Publish $keyPair->publicKeyBase64url at:
// https://yourdomain.com/.well-known/venmail-agent/billing
// Or as a DNS TXT record on _venmail.yourdomain.com
// Sign an outgoing message
$result = Signer::signMessage(
'<p>Please process invoice #8821 for $5,000 USD.</p>',
[
'from' => 'billing@yourdomain.com',
'to' => 'vendor@external.com',
'subject' => 'Invoice #8821',
'date' => gmdate('D, d M Y H:i:s +0000'),
],
[
'agentId' => 'billing@yourdomain.com',
'privateKey' => $keyPair->privateKey,
'verifyMethods' => ['well-known', 'dns'],
'keyVersion' => 1,
]
);
// $result->headers contains all X-Venmail-* headers
// Pass them when sending via your email APIuse Venmail\VVS\Verifier;
$result = Verifier::verifyMessage(
$incomingVvsHeaders, // ['X-Venmail-Agent' => '...', ...]
$emailBody,
['from' => '...', 'to' => '...', 'subject' => '...', 'date' => '...']
);
echo $result->trustLevel; // VERIFIED | PARTIAL | FAILED | UNKNOWN
echo $result->agentId; // billing@company.com
echo $result->error; // null or failure reasonuse Venmail\VVS\Helpers\DnsRecordGenerator;
$record = DnsRecordGenerator::generate('billing', $keyPair->publicKeyBase64url, 1);
// "v=VVS1; agent=billing; pubkey=...; kv=1; status=active"
// Add as TXT record on _venmail.yourdomain.comuse Venmail\VVS\Helpers\WellKnownRoute;
// In routes/web.php
WellKnownRoute::laravelRoute(function (string $agentName) {
$key = VvsAgentKey::where('agent_name', $agentName)
->where('status', 'active')
->latest('key_version')
->first();
if (!$key) return null;
return [
'agent_id' => $agentName . '@' . config('app.domain'),
'public_key' => $key->public_key_base64url,
'key_version' => $key->key_version,
'status' => 'active',
'algorithm' => 'ed25519',
];
})();| Level | Meaning |
|---|---|
| VERIFIED | Signature valid, key resolved via .well-known or DNS |
| PARTIAL | Signature valid, key from embedded email header only |
| FAILED | Headers present but verification failed |
| UNKNOWN | No VVS headers — normal email |
canonicalizeBody(string $rawBody): stringcanonicalizeHeaders(string $from, string $to, string $subject, string $date): stringbuildCanonicalPayload(string $agentId, string $timestamp, string $nonce, string $contentHash, string $canonicalHeaders): stringcomputeContentHash(string $canonicalBody): stringbase64urlEncode(string $data): stringbase64urlDecode(string $data): string
signMessage(string $body, array $emailHeaders, array $options): SignResultgenerateNonce(): string
verifyMessage(array $headers, string $body, array $emailHeaders, array $options): VerifyResult
generate(): KeyPair
resolve(string $agentName, string $domain, string $method, ?string $embeddedKey): ?array
- @venmail/vsm — Node.js/TypeScript SDK
- Venmail API Docs — Full API documentation
MIT — see LICENSE.