{"id":35562054,"url":"https://github.com/scgis-wales/dcert","last_synced_at":"2026-04-01T22:30:52.093Z","repository":{"id":313686234,"uuid":"1051721019","full_name":"SCGIS-Wales/dcert","owner":"SCGIS-Wales","description":"CLI tool that decodes PEM base64 decoded TLS certificates","archived":false,"fork":false,"pushed_at":"2026-02-21T19:14:20.000Z","size":415,"stargazers_count":2,"open_issues_count":0,"forks_count":1,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-02-21T19:23:44.216Z","etag":null,"topics":["base64-decoding","certificate-management","cli","keystore","mcp-client","mcp-server","pem","pfx","rust","tls","tls-certificate","truststore"],"latest_commit_sha":null,"homepage":"https://pypi.org/project/dcert/","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/SCGIS-Wales.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-09-06T15:27:54.000Z","updated_at":"2026-02-21T19:14:23.000Z","dependencies_parsed_at":"2026-03-03T20:01:00.361Z","dependency_job_id":null,"html_url":"https://github.com/SCGIS-Wales/dcert","commit_stats":null,"previous_names":["scgis-wales/dcert"],"tags_count":37,"template":false,"template_full_name":null,"purl":"pkg:github/SCGIS-Wales/dcert","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SCGIS-Wales%2Fdcert","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SCGIS-Wales%2Fdcert/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SCGIS-Wales%2Fdcert/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SCGIS-Wales%2Fdcert/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/SCGIS-Wales","download_url":"https://codeload.github.com/SCGIS-Wales/dcert/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SCGIS-Wales%2Fdcert/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30057588,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-03T18:21:05.932Z","status":"ssl_error","status_checked_at":"2026-03-03T18:20:59.341Z","response_time":61,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["base64-decoding","certificate-management","cli","keystore","mcp-client","mcp-server","pem","pfx","rust","tls","tls-certificate","truststore"],"created_at":"2026-01-04T13:08:07.573Z","updated_at":"2026-04-01T22:30:52.077Z","avatar_url":"https://github.com/SCGIS-Wales.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n  \u003cimg src=\"assets/logo.svg\" alt=\"dcert logo\" width=\"400\"\u003e\n  \u003ch1\u003edcert\u003c/h1\u003e\n  \u003cp\u003e\u003cstrong\u003eTLS Certificate Decoder \u0026 Validator\u003c/strong\u003e\u003c/p\u003e\n  \u003cp\u003eA Rust CLI and MCP server for X.509 certificate analysis, format conversion, and key verification.\u003cbr\u003eReads certificates from PEM files or HTTPS endpoints. Validates TLS connections, checks revocation status,\u003cbr\u003econverts between PFX and PEM formats, and integrates with AI-powered IDEs via the Model Context Protocol (MCP).\u003c/p\u003e\n  \u003cp\u003e\n    \u003ca href=\"https://github.com/SCGIS-Wales/dcert/actions/workflows/ci.yml\"\u003e\u003cimg src=\"https://github.com/SCGIS-Wales/dcert/actions/workflows/ci.yml/badge.svg?branch=main\" alt=\"CI/CD Pipeline\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://pypi.org/project/dcert/\"\u003e\u003cimg src=\"https://img.shields.io/pypi/v/dcert\" alt=\"PyPI version\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://pypi.org/project/dcert/\"\u003e\u003cimg src=\"https://img.shields.io/pypi/dm/dcert\" alt=\"PyPI Downloads\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://pypi.org/project/dcert/\"\u003e\u003cimg src=\"https://img.shields.io/pypi/pyversions/dcert\" alt=\"Python\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://github.com/SCGIS-Wales/dcert\"\u003e\u003cimg src=\"https://img.shields.io/badge/Rust-stable-000000?logo=rust\u0026logoColor=white\" alt=\"Rust\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://opensource.org/licenses/MIT\"\u003e\u003cimg src=\"https://img.shields.io/badge/License-MIT-yellow.svg\" alt=\"License: MIT\"\u003e\u003c/a\u003e\n  \u003c/p\u003e\n\u003c/div\u003e\n\n---\n\n## Table of Contents\n\n- [Quick Start](#quick-start)\n- [Installation](#installation)\n- [Commands](#commands)\n  - [dcert [check] -- Certificate Analysis](#dcert-check--certificate-analysis-default)\n  - [dcert csr -- CSR Creation \u0026 Validation](#dcert-csr--csr-creation--validation)\n  - [dcert convert -- Format Conversion](#dcert-convert--format-conversion)\n  - [dcert verify-key -- Key Matching](#dcert-verify-key--key-matching)\n  - [dcert vault -- HashiCorp Vault PKI](#dcert-vault--hashicorp-vault-pki)\n- [MCP Server (AI IDE Integration)](#mcp-server-ai-ide-integration)\n  - [Proxy and Timeout Configuration](#proxy-and-timeout-configuration)\n  - [Troubleshooting](#troubleshooting)\n  - [HTTP Transport Mode](#http-transport-mode)\n- [Features by Topic](#features-by-topic)\n- [Use Cases](#use-cases)\n- [Python Package](#python-package)\n- [Development](#development)\n- [License](#license)\n\n## Quick Start\n\n```bash\n# Install via Homebrew\nbrew tap SCGIS-Wales/homebrew-tap https://github.com/SCGIS-Wales/homebrew-tap.git\nbrew install dcert\n\n# Analyze a live HTTPS endpoint (bare hostname or full URL)\ndcert api.example.com\ndcert https://www.google.com\n\n# Read PEM from a pipe\ncat certificate.pem | dcert\n\n# Check certificate expiry (CI/CD gate)\ndcert https://your-api.com --expiry-warn 30\n\n# Convert PFX to PEM\ndcert convert pfx-to-pem client.pfx --password secret --output-dir ./certs\n\n# Verify a private key matches a certificate\ndcert verify-key cert.pem --key private.key\n\n# Auto-discover and verify all cert/key pairs in a directory\ndcert verify-key\n\n# Create a new CSR with RSA 4096 key\ndcert csr create --cn api.example.com --org \"My Corp\" --country GB\n\n# Validate a CSR for compliance\ndcert csr validate my-cert.csr\n\n# Issue a TLS certificate from HashiCorp Vault PKI\ndcert vault issue --cn www.example.com --role my-role\n\n# Renew a certificate stored in Vault KV\ndcert vault renew secret/certs/www-example-com --role my-role\n```\n\n## Installation\n\n### Homebrew (recommended — macOS and Linux)\n\nHomebrew is the recommended installation method. On Linux it builds from source, which avoids glibc compatibility issues and works on Ubuntu 22.04 and later.\n\n```bash\nbrew tap SCGIS-Wales/homebrew-tap https://github.com/SCGIS-Wales/homebrew-tap.git\nbrew install dcert\n```\n\n\u003e **Note:** If you don't have Homebrew on Linux, install it first:\n\u003e ```bash\n\u003e /bin/bash -c \"$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)\"\n\u003e ```\n\n### Prebuilt binaries\n\nDownload from the [Releases](https://github.com/SCGIS-Wales/dcert/releases) page. Each release includes `dcert` (CLI) and `dcert-mcp` (MCP server). Prebuilt Linux binaries require Ubuntu 22.04 (glibc 2.35) or later.\n\n```bash\ncurl -L https://github.com/SCGIS-Wales/dcert/releases/latest/download/dcert-x86_64-unknown-linux-gnu.tar.gz | tar xz\nchmod +x dcert dcert-mcp\nsudo mv dcert dcert-mcp /usr/local/bin/\n```\n\n### Build from source\n\n```bash\ngit clone https://github.com/SCGIS-Wales/dcert.git\ncd dcert\ncargo build --release\n# Binaries: target/release/dcert and target/release/dcert-mcp\n```\n\n### Docker\n\n```bash\ndocker pull ghcr.io/scgis-wales/dcert:main\n\n# CLI\ndocker run --rm ghcr.io/scgis-wales/dcert:main https://www.google.com\n\n# Local PEM file\ndocker run --rm -v \"$PWD:/data\" ghcr.io/scgis-wales/dcert:main /data/cert.pem\n\n# MCP server\ndocker run --rm -i --entrypoint dcert-mcp ghcr.io/scgis-wales/dcert:main\n```\n\n---\n\n## Commands\n\ndcert uses subcommands to organize its features. The `check` subcommand is the default and can be omitted:\n\n```\ndcert \u003ctargets\u003e [OPTIONS]              # Certificate analysis (default, same as 'dcert check')\ndcert csr create [OPTIONS]             # Create a CSR and private key\ndcert csr validate \u003cCSR_FILE\u003e          # Validate a CSR for compliance\ndcert convert \u003cMODE\u003e [OPTIONS]         # Format conversion (PFX/PEM/keystore/truststore)\ndcert verify-key \u003ctarget\u003e --key \u003cKEY\u003e  # Key-certificate matching (single pair)\ndcert verify-key [--dir \u003cDIR\u003e]         # Auto-discover and verify all cert/key pairs\ndcert vault issue [OPTIONS]            # Issue a TLS certificate from Vault PKI\ndcert vault sign [OPTIONS]             # Sign a CSR using Vault PKI\ndcert vault revoke [OPTIONS]           # Revoke a certificate in Vault PKI\ndcert vault list [OPTIONS]             # List certificates issued by Vault PKI\ndcert vault store [OPTIONS] \u003cPATH\u003e     # Store cert+key in Vault KV\ndcert vault validate \u003cPATH\u003e            # Validate a certificate in Vault KV\ndcert vault renew \u003cPATH\u003e [OPTIONS]     # Renew a certificate in Vault KV\n```\n\n### dcert [check] -- Certificate Analysis (default)\n\nAnalyze TLS certificates from PEM files or HTTPS endpoints. The `check` keyword is optional -- `dcert https://example.com` and `dcert check https://example.com` are equivalent.\n\n```bash\n# Fetch and analyze certificates from HTTPS\ndcert https://www.google.com\n\n# Bare hostname (auto-prepends https://)\ndcert api.example.com\n\n# Analyze a local PEM file\ndcert certificate.pem\n\n# Read PEM data from stdin (pipe)\ncat certificate.pem | dcert\necho \"\u003cbase64-pem\u003e\" | base64 --decode | dcert\ncat certificate.pem | dcert -\n\n# Multiple targets\ndcert https://www.google.com https://github.com cert.pem\n\n# Pipe target names from stdin (one per line)\necho -e \"https://google.com\\nhttps://github.com\" | dcert -\n\n# JSON or YAML output\ndcert https://example.com --format json\ndcert https://example.com --format yaml\n\n# SHA-256 fingerprints and certificate extensions\ndcert https://example.com --fingerprint --extensions\n\n# Expiry warning (exit code 1 if expiring within 30 days)\ndcert https://example.com --expiry-warn 30\n\n# OCSP revocation check\ndcert https://example.com --check-revocation\n\n# Compare certificates between two targets\ndcert --diff https://staging.example.com https://prod.example.com\n\n# Monitor certificates every 60 seconds\ndcert --watch 60 https://example.com\n\n# Export certificate chain to PEM file\ndcert https://www.google.com --export-pem chain.pem\n\n# Export excluding expired certificates\ndcert https://www.google.com --export-pem chain.pem --exclude-expired\n\n# Sort by expiry date\ndcert certificates.pem --sort-expiry asc\n\n# Only show expired certificates\ndcert certificates.pem --expired-only\n\n# Compliance report (CA/B Forum Baseline Requirements)\ndcert https://example.com --compliance\ndcert certificate.pem --compliance\n\n# Compliance report in JSON (for CI/CD)\ndcert https://example.com --compliance --format json\n```\n\n#### TLS Options\n\n```bash\n# Require TLS 1.3\ndcert --min-tls 1.3 https://example.com\n\n# Force TLS 1.2 only\ndcert --min-tls 1.2 --max-tls 1.2 https://example.com\n\n# Specific TLS 1.2 ciphers\ndcert --cipher-list \"ECDHE+AESGCM:CHACHA20\" --max-tls 1.2 https://example.com\n\n# TLS 1.3 cipher suites\ndcert --cipher-suites \"TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256\" https://example.com\n\n# HTTP/2 ALPN negotiation\ndcert --http-protocol http2 https://example.com\n\n# SNI override\ndcert https://10.0.0.1 --sni api.example.com\n\n# Skip TLS verification (self-signed certs)\ndcert https://localhost:8443 --no-verify\n```\n\n#### mTLS (Mutual TLS)\n\n```bash\n# Client certificate with PEM files\ndcert https://api.internal.com --client-cert client.pem --client-key client-key.pem\n\n# Client certificate with PKCS12/PFX\ndcert https://api.internal.com --pkcs12 client.pfx --cert-password secret\n\n# Custom CA bundle (overrides system CAs)\ndcert https://internal.server --ca-cert corporate-ca.pem\n\n# Combine mTLS with custom CA\ndcert https://api.internal.com --client-cert client.pem --client-key client-key.pem --ca-cert corporate-ca.pem\n```\n\n#### HTTP Options\n\n```bash\n# Custom headers and method\ndcert https://api.example.com --method POST --header \"Authorization:Bearer token\"\n\n# POST with inline data\ndcert https://api.example.com -d '{\"key\":\"value\"}' --header \"Content-Type:application/json\"\n\n# POST with data from file\ndcert https://api.example.com --data-file body.json\n\n# Custom timeout\ndcert https://slow-server.example.com --timeout 30 --read-timeout 15\n```\n\n#### Full Options Reference\n\n```\ndcert [check] [OPTIONS] [TARGETS]...\n\nArguments:\n  [TARGETS]...                         PEM file(s), HTTPS URL(s), bare hostnames, or '-' for stdin\n                                       Omit targets to read PEM data from a pipe\n\nOptions:\n  -f, --format \u003cFORMAT\u003e                Output format [pretty, json, yaml] (default: pretty)\n      --expired-only                   Show only expired certificates\n      --export-pem \u003cFILE\u003e              Export fetched PEM chain to a file\n      --exclude-expired                Exclude expired certs from export\n      --sort-expiry \u003cORDER\u003e            Sort by expiry [asc, desc]\n      --method \u003cMETHOD\u003e                HTTP method [get, post, head, options] (default: get)\n      --header \u003cKEY:VALUE\u003e             Custom HTTP headers (repeatable)\n  -d, --data \u003cDATA\u003e                    Request body (implies POST)\n      --data-file \u003cFILE\u003e               Request body from file (implies POST)\n      --http-protocol \u003cPROTO\u003e          HTTP protocol [http1-1, http2] (default: http1-1)\n      --min-tls \u003cVERSION\u003e              Minimum TLS version [1.2, 1.3]\n      --max-tls \u003cVERSION\u003e              Maximum TLS version [1.2, 1.3]\n      --cipher-list \u003cSTRING\u003e           Allowed TLS 1.2 ciphers (OpenSSL format)\n      --cipher-suites \u003cSUITES\u003e         Allowed TLS 1.3 cipher suites (colon-separated)\n      --no-verify                      Disable TLS verification (insecure)\n      --timeout \u003cSECONDS\u003e              Connection timeout (default: 10)\n      --read-timeout \u003cSECONDS\u003e         Read timeout (default: 5)\n      --sni \u003cHOSTNAME\u003e                 Override SNI hostname\n      --fingerprint                    Show SHA-256 fingerprints\n      --extensions                     Show certificate extensions\n      --expiry-warn \u003cDAYS\u003e             Warn if expiring within N days (exit code 1)\n      --diff                           Compare certificates between two targets\n      --watch \u003cSECONDS\u003e                Re-check at interval\n      --compliance                      Run compliance checks (CA/B Forum, DigiCert, X9)\n      --check-revocation               Check OCSP revocation status\n      --debug                          Verbose OSI-layer diagnostics on stderr\n      --client-cert \u003cPATH\u003e             Client certificate PEM for mTLS\n      --client-key \u003cPATH\u003e              Client private key PEM for mTLS\n      --pkcs12 \u003cPATH\u003e                  PKCS12/PFX file for mTLS (alternative to --client-cert/--client-key)\n      --cert-password \u003cPASS\u003e           PKCS12 password (env: DCERT_CERT_PASSWORD)\n      --ca-cert \u003cPATH\u003e                 Custom CA bundle PEM (overrides system CAs)\n  -h, --help                           Print help\n  -V, --version                        Print version\n```\n\n#### Exit Codes\n\n| Code | Meaning |\n|------|---------|\n| 0 | Success -- all certificates valid |\n| 1 | Expiry warning -- certificate(s) expiring within `--expiry-warn` threshold |\n| 2 | Error -- connection failure, file not found, or processing error |\n| 3 | TLS verification failed |\n| 4 | Certificate expired |\n| 5 | Certificate revoked (OCSP) |\n| 6 | Client certificate error (invalid, unreadable, wrong password) |\n| 7 | Key mismatch (private key doesn't match certificate) |\n\n---\n\n### dcert csr -- CSR Creation \u0026 Validation\n\nCreate PKCS#10 Certificate Signing Requests (CSRs) and validate existing CSRs for compliance with CA/B Forum Baseline Requirements, DigiCert, and X9 standards.\n\n#### Create a CSR\n\n```bash\n# RSA 4096 (default) — guided interactive mode (omit --cn)\ndcert csr create\n\n# RSA 4096 with subject fields\ndcert csr create --cn api.example.com --org \"My Corp\" --country GB\n\n# ECDSA P-256 (recommended modern) with multiple SANs\ndcert csr create --cn www.example.com --key-algo ecdsa-p256 \\\n  --san DNS:www.example.com --san DNS:example.com --san IP:10.0.0.1\n\n# Encrypted private key\ndcert csr create --cn secure.example.com --encrypt-key --key-password \"$(read -sp 'Password: ' p \u0026\u0026 echo $p)\"\n\n# Custom output paths and JSON output\ndcert csr create --cn api.example.com --csr-out api.csr --key-out api.key --format json\n\n# OU metadata identifiers (for internal/private PKI)\ndcert csr create --cn app.internal.corp --ou \"AppId:my-service-123\" --ou \"Team:Platform\"\n```\n\n#### Validate a CSR\n\n```bash\n# Pretty compliance report\ndcert csr validate my-cert.csr\n\n# JSON output (for CI/CD pipelines)\ndcert csr validate my-cert.csr --format json\n\n# Strict mode (warnings become errors)\ndcert csr validate my-cert.csr --strict\n```\n\n#### Key Algorithm Options\n\n| Algorithm | Flag | Description |\n|-----------|------|-------------|\n| RSA 4096 | `--key-algo rsa-4096` | Default. Strong, widely compatible. |\n| RSA 2048 | `--key-algo rsa-2048` | Minimum accepted by CAs. |\n| ECDSA P-256 | `--key-algo ecdsa-p256` | Recommended modern choice. Faster, equivalent to RSA 3072. |\n| ECDSA P-384 | `--key-algo ecdsa-p384` | High-security requirements. |\n| Ed25519 | `--key-algo ed25519` | Modern EdDSA. Compact signatures, high performance. Requires OpenSSL 3.x. |\n\n#### Compliance Checks\n\nThe validator checks against CA/B Forum Baseline Requirements, DigiCert, and X9 standards:\n\n- **Key size**: Minimum RSA 2048-bit / ECDSA P-256\n- **Signature algorithm**: SHA-256+ required, SHA-1 rejected\n- **Subject Alternative Names**: Required for all modern certificates\n- **OU deprecation**: Warning for publicly-trusted CAs (CA/B Forum Ballot SC47v2, Sep 2022)\n- **Country code**: ISO 3166-1 alpha-2 validation\n- **CN in SAN**: CN should be included in SANs per RFC 6125\n\n#### Full Options Reference\n\n```\ndcert csr create [OPTIONS]\n\nOptions:\n      --cn \u003cNAME\u003e          Common Name (FQDN). Omit for interactive mode.\n      --org \u003cNAME\u003e         Organization (O)\n      --ou \u003cNAME\u003e          Organizational Unit (repeatable, supports metadata e.g., \"AppId:xxx\")\n      --country \u003cCODE\u003e     Two-letter country code (e.g., GB, US)\n      --state \u003cNAME\u003e       State or province (ST)\n      --locality \u003cNAME\u003e    City or locality (L)\n      --email \u003cEMAIL\u003e      Email address\n      --san \u003cTYPE:VALUE\u003e   Subject Alternative Name (repeatable, e.g., DNS:www.example.com, IP:10.0.0.1)\n      --key-algo \u003cALGO\u003e    Key algorithm [rsa-4096, rsa-2048, ecdsa-p256, ecdsa-p384, ed25519] (default: rsa-4096)\n      --encrypt-key        Encrypt the private key (AES-256-CBC, PKCS#8)\n      --key-password \u003cPW\u003e  Password for key encryption (env: DCERT_KEY_PASSWORD)\n      --csr-out \u003cFILE\u003e     Output CSR file path (default: \u003ccn\u003e.csr)\n      --key-out \u003cFILE\u003e     Output key file path (default: \u003ccn\u003e.key)\n  -f, --format \u003cFORMAT\u003e    Output format [pretty, json, yaml] (default: pretty)\n\ndcert csr validate [OPTIONS] \u003cCSR_FILE\u003e\n\nArguments:\n  \u003cCSR_FILE\u003e              PEM-encoded CSR file to validate\n\nOptions:\n      --strict             Treat warnings as errors\n  -f, --format \u003cFORMAT\u003e   Output format [pretty, json, yaml] (default: pretty)\n```\n\n---\n\n### dcert convert -- Format Conversion\n\nConvert between certificate formats. Four modes are available:\n\n#### pfx-to-pem\n\nExtract certificate, key, and CA chain from a PKCS12/PFX file into separate PEM files.\n\n```bash\ndcert convert pfx-to-pem server.pfx --password secret --output-dir ./certs\n# Produces: ./certs/cert.pem, ./certs/key.pem, ./certs/ca.pem (if CA certs present)\n```\n\n#### pem-to-pfx\n\nBundle PEM certificate and private key into a PKCS12/PFX file.\n\n```bash\ndcert convert pem-to-pfx --cert server.pem --key server-key.pem --output server.pfx --password secret\n\n# Include CA chain\ndcert convert pem-to-pfx --cert server.pem --key server-key.pem --ca ca-chain.pem --output server.pfx --password secret\n```\n\n#### create-keystore\n\nCreate a PKCS12 keystore from PEM certificate and key (Java-compatible since JDK 9, where PKCS12 is the default keystore type).\n\n```bash\ndcert convert create-keystore --cert server.pem --key server-key.pem --output keystore.p12 --password changeit --alias myserver\n```\n\nTo convert to JKS format if needed:\n\n```bash\nkeytool -importkeystore -srckeystore keystore.p12 -srcstoretype PKCS12 -destkeystore keystore.jks -deststoretype JKS\n```\n\n#### create-truststore\n\nCreate a PKCS12 truststore from CA certificate PEM files.\n\n```bash\ndcert convert create-truststore ca1.pem ca2.pem --output truststore.p12 --password changeit\n```\n\n---\n\n### dcert verify-key -- Key Matching\n\nVerify that a private key matches a certificate. Works with PEM files and HTTPS endpoints. When run without arguments, auto-discovers matching cert/key pairs in the current directory.\n\n```bash\n# Verify a specific pair\ndcert verify-key cert.pem --key private.key\n\n# Verify against an HTTPS endpoint\ndcert verify-key https://example.com --key private.key\n\n# Auto-discover all cert/key pairs in the current directory\ndcert verify-key\n\n# Auto-discover in a specific directory\ndcert verify-key --dir /etc/ssl/certs\n\n# JSON output\ndcert verify-key cert.pem --key private.key --format json\ndcert verify-key --format json\n```\n\n**Auto-discovery** scans for `.crt` and `.pem` files that have a matching `.key` file with the same base name (e.g. `server.crt` + `server.key`, `app.pem` + `app.key`). Files without a matching key are skipped.\n\nReturns key type, key size, certificate subject, and whether the key matches. Exit code 7 on mismatch.\n\n---\n\n### dcert vault -- HashiCorp Vault PKI\n\nIssue, sign, revoke, list, store, validate, and renew TLS certificates using HashiCorp Vault's PKI Secrets Engine. Supports interactive wizard mode (omit required args) or fully non-interactive CLI usage.\n\n#### Prerequisites\n\nSet these environment variables before using vault commands:\n\n| Variable | Required | Description |\n|----------|----------|-------------|\n| `VAULT_ADDR` | Yes | Vault server URL (e.g., `https://vault.example.com:8200`) |\n| `VAULT_TOKEN` | No* | Vault authentication token |\n| `VAULT_CACERT` | No | Custom CA certificate PEM file for Vault TLS |\n| `VAULT_CAPATH` | No | Directory of CA PEM files for Vault TLS |\n| `VAULT_SKIP_VERIFY` | No | Set to `1` to skip TLS verification (insecure) |\n| `SSL_CERT_FILE` | No | Fallback CA cert file (used if `VAULT_CACERT` is not set) |\n| `SSL_CERT_DIR` | No | Fallback CA cert directory (used if `VAULT_CAPATH` is not set) |\n\n\\* Token is discovered in order: `VAULT_TOKEN` env var, then `~/.vault-token` file.\n\n**TLS configuration**: By default, dcert uses your system's native CA store. For corporate Vault servers using internal CAs, set `VAULT_CACERT` or `SSL_CERT_FILE` to point to your CA bundle. Use `--debug` to diagnose TLS issues:\n\n```bash\n# Use a custom CA certificate\nexport VAULT_CACERT=/path/to/corporate-ca.pem\ndcert vault issue --cn www.example.com --role my-role\n\n# Or via CLI flag\ndcert vault --vault-cacert /path/to/ca.pem issue --cn www.example.com --role my-role\n\n# Debug TLS connectivity issues\ndcert vault --debug issue --cn www.example.com --role my-role\n\n# Skip TLS verification (insecure, for testing only)\ndcert vault --skip-verify issue --cn www.example.com --role my-role\n```\n\n#### Role Discovery\n\nIf `--role` is not provided, dcert looks up your token's policies (`vault token lookup-self`) and extracts role names from policies that follow a dotted naming convention (`prefix.rolename.permission`). The second segment is used as the role name. If multiple roles are found, you are prompted to select one.\n\n#### Issue a Certificate\n\nVault generates a new private key and certificate via the PKI engine.\n\n```bash\n# Interactive wizard (guided step-by-step)\ndcert vault issue\n\n# Non-interactive with all options\ndcert vault issue --cn www.example.com --role my-role \\\n  --san \"DNS:*.example.com\" --ip-san 10.0.0.1 --ttl 8760h\n\n# Output as PFX instead of PEM\ndcert vault issue --cn www.example.com --role my-role --pfx-password secret\n\n# Issue and store in Vault KV\ndcert vault issue --cn www.example.com --role my-role \\\n  --store-path secret/company/project/certs/www-example-com\n\n# Custom PKI mount point\ndcert vault issue --cn www.example.com --role my-role --mount pki_intermediate\n```\n\n#### Sign a CSR\n\nSubmit an existing CSR to Vault PKI for signing (no private key is generated).\n\n```bash\n# Interactive wizard\ndcert vault sign\n\n# Non-interactive\ndcert vault sign --csr-file server.csr --role my-role --ttl 8760h\n\n# Override CN from CSR\ndcert vault sign --csr-file server.csr --role my-role --cn override.example.com\n\n# Sign with IP SANs\ndcert vault sign --csr-file server.csr --role my-role --ip-san 10.0.0.1 --ip-san 192.168.1.1\n```\n\n#### Revoke a Certificate\n\n```bash\n# Revoke by serial number\ndcert vault revoke --serial \"1a:2b:3c:4d:5e\"\n\n# Revoke by PEM certificate file\ndcert vault revoke --cert-file server.crt\n```\n\n#### List Certificates\n\n```bash\n# List all issued certificates (serial numbers only)\ndcert vault list\n\n# Fetch and display details for each certificate\ndcert vault list --show-details\n\n# Filter by status\ndcert vault list --show-details --expired-only\ndcert vault list --show-details --valid-only\n\n# Export to JSON, CSV, or Excel\ndcert vault list --show-details --export certs.json\ndcert vault list --show-details --export certs.csv\ndcert vault list --show-details --export certs.xlsx\n\n# JSON output\ndcert vault list --show-details --format json\n```\n\n#### Store in Vault KV\n\nStore a local certificate and private key in Vault KV (v1 by default, v2 with `--kv-version 2`).\n\n```bash\ndcert vault store --cert-file server.crt --key-file server.key \\\n  secret/company/project/certs/www-example-com\n\n# Use KV v2\ndcert vault store --cert-file server.crt --key-file server.key \\\n  --kv-version 2 secret/company/project/certs/www-example-com\n\n# Custom key names in KV\ndcert vault store --cert-file server.crt --key-file server.key \\\n  --cert-key tls_cert --key-key tls_key \\\n  secret/company/project/certs/www-example-com\n```\n\n#### Validate from Vault KV\n\nRead a certificate and key from Vault KV, validate them, and display certificate details (same output as `dcert check`). Also verifies the private key matches the certificate.\n\n```bash\ndcert vault validate secret/company/project/certs/www-example-com\n\n# Custom key names\ndcert vault validate secret/company/project/certs/www-example-com \\\n  --cert-key tls_cert --key-key tls_key\n\n# JSON output\ndcert vault validate secret/company/project/certs/www-example-com --format json\n```\n\n#### Renew a Certificate\n\nRead an existing certificate from Vault KV, extract its CN and SANs, issue a new certificate with the same parameters, and overwrite the KV entry. Optionally override SANs or IP SANs.\n\n```bash\ndcert vault renew secret/company/project/certs/www-example-com --role my-role\n\n# Custom TTL and mount\ndcert vault renew secret/company/project/certs/www-example-com \\\n  --role my-role --ttl 2160h --mount pki_intermediate\n\n# Override SANs on renew\ndcert vault renew secret/company/project/certs/www-example-com --role my-role \\\n  --san app.example.com --ip-san 10.0.0.1\n```\n\n#### Permission Errors\n\nAll Vault API calls produce clear, actionable error messages on permission denial:\n\n```\nError: Permission denied by Vault.\n\n  Endpoint: POST vault_intermediate/issue/my-role\n  Required: create capability on \"vault_intermediate/issue/my-role\"\n\n  Ask your Vault administrator to add this policy to your token:\n    path \"vault_intermediate/issue/my-role\" {\n      capabilities = [\"create\"]\n    }\n```\n\n#### Full Options Reference\n\n```\ndcert vault [GLOBAL OPTIONS] \u003cSUBCOMMAND\u003e [OPTIONS]\n\nGlobal Vault Options:\n      --skip-verify           Skip TLS verification (insecure). Also: VAULT_SKIP_VERIFY=1\n      --vault-cacert \u003cPATH\u003e   Custom CA certificate PEM file. Also: VAULT_CACERT env var\n      --debug                 Show verbose TLS and API diagnostics\n\ndcert vault issue [OPTIONS]\n      --cn \u003cNAME\u003e           Common Name. Omit for interactive wizard.\n      --san \u003cSAN\u003e           Subject Alternative Names (repeatable)\n      --ip-san \u003cIP\u003e         IP SANs (repeatable)\n      --ttl \u003cTTL\u003e           Certificate TTL (default: 8760h)\n      --role \u003cROLE\u003e         Vault PKI role name\n      --mount \u003cMOUNT\u003e       Vault PKI mount point (default: vault_intermediate)\n      --output \u003cNAME\u003e       Output file base name (default: sanitised CN)\n  -f, --format \u003cFORMAT\u003e     Output format [pretty, json, yaml]\n      --pfx-password \u003cPW\u003e   Output as PFX instead of PEM (env: DCERT_CERT_PASSWORD)\n      --store-path \u003cPATH\u003e   Store cert+key in Vault KV after issuance\n      --kv-version \u003c1|2\u003e    Vault KV version for --store-path (default: 1)\n\ndcert vault sign [OPTIONS]\n      --csr-file \u003cFILE\u003e     CSR PEM file. Omit for interactive wizard.\n      --cn \u003cNAME\u003e           Override CN from CSR\n      --san \u003cSAN\u003e           Additional SANs (repeatable)\n      --ip-san \u003cIP\u003e         IP SANs (repeatable)\n      --ttl \u003cTTL\u003e           Certificate TTL (default: 8760h)\n      --role \u003cROLE\u003e         Vault PKI role name\n      --mount \u003cMOUNT\u003e       PKI mount point (default: vault_intermediate)\n      --output \u003cNAME\u003e       Output file base name\n  -f, --format \u003cFORMAT\u003e     Output format [pretty, json, yaml]\n      --store-path \u003cPATH\u003e   Store certificate in Vault KV after signing\n      --kv-version \u003c1|2\u003e    Vault KV version for --store-path (default: 1)\n\ndcert vault revoke [OPTIONS]\n      --serial \u003cSERIAL\u003e     Certificate serial number (hex, colon or hyphen-separated)\n      --cert-file \u003cFILE\u003e    PEM certificate file to revoke\n      --mount \u003cMOUNT\u003e       PKI mount point (default: vault_intermediate)\n\ndcert vault list [OPTIONS]\n      --mount \u003cMOUNT\u003e       PKI mount point (default: vault_intermediate)\n  -f, --format \u003cFORMAT\u003e     Output format [pretty, json, yaml]\n      --show-details        Fetch details for each certificate\n      --expired-only        Show only expired certificates\n      --valid-only          Show only valid certificates\n      --export \u003cFILE\u003e       Export to JSON, CSV, or XLSX file\n\ndcert vault store [OPTIONS] \u003cPATH\u003e\n      --cert-file \u003cFILE\u003e    Local PEM certificate file (required)\n      --key-file \u003cFILE\u003e     Local PEM private key file (required)\n      --cert-key \u003cNAME\u003e     KV key name for certificate (default: cert)\n      --key-key \u003cNAME\u003e      KV key name for private key (default: key)\n      --kv-version \u003c1|2\u003e    Vault KV version (default: 1)\n\ndcert vault validate [OPTIONS] \u003cPATH\u003e\n      --cert-key \u003cNAME\u003e     KV key name for certificate (default: cert)\n      --key-key \u003cNAME\u003e      KV key name for private key (default: key)\n      --kv-version \u003c1|2\u003e    Vault KV version (default: 1)\n  -f, --format \u003cFORMAT\u003e     Output format [pretty, json, yaml]\n\ndcert vault renew [OPTIONS] \u003cPATH\u003e\n      --role \u003cROLE\u003e         PKI role name for issuing new certificate\n      --mount \u003cMOUNT\u003e       PKI mount point (default: vault_intermediate)\n      --ttl \u003cTTL\u003e           TTL for new certificate (default: 8760h)\n      --cert-key \u003cNAME\u003e     KV key name for certificate (default: cert)\n      --key-key \u003cNAME\u003e      KV key name for private key (default: key)\n      --kv-version \u003c1|2\u003e    Vault KV version (default: 1)\n      --san \u003cSAN\u003e           Override SANs from existing cert (repeatable)\n      --ip-san \u003cIP\u003e         Override IP SANs from existing cert (repeatable)\n  -f, --format \u003cFORMAT\u003e     Output format [pretty, json, yaml]\n```\n\n---\n\n## MCP Server (AI IDE Integration)\n\n`dcert-mcp` is a Model Context Protocol server that exposes dcert's capabilities as tools for AI-powered IDEs. It supports two transport modes: **stdio** (default, for IDE integration) and **HTTP** (for remote deployment with optional OIDC/OAuth2 authentication).\n\n### Tools\n\n| Tool | Description |\n|------|-------------|\n| `analyze_certificate` | Decode and analyze TLS certificates. Returns subject, issuer, SANs, validity, fingerprints, extensions, TLS connection info, and OSI-layer diagnostics. Supports mTLS. |\n| `check_expiry` | Check if certificates expire within N days. Returns `ALL_VALID`, `EXPIRING_SOON`, or `ALREADY_EXPIRED`. Supports mTLS. |\n| `check_revocation` | Check OCSP revocation status via the certificate's OCSP responder. Supports mTLS. |\n| `compare_certificates` | Compare certificates between two targets side-by-side. |\n| `tls_connection_info` | Get TLS connection details: protocol, cipher, ALPN, latency, verification, diagnostics. Supports mTLS. |\n| `export_pem` | Export TLS certificate chain from an HTTPS endpoint as PEM. Optionally saves to file and can exclude expired certs. Supports mTLS. |\n| `create_csr` | Create a PKCS#10 CSR and private key. Supports RSA/ECDSA, OU metadata, and encrypted keys. Compliant with CA/B Forum, DigiCert, and X9 standards. |\n| `validate_csr` | Validate a CSR for compliance with CA/B Forum Baseline Requirements, DigiCert, and X9 standards. Returns findings with severity levels. |\n| `validate_certificate` | Run compliance checks on a certificate (PEM file or HTTPS endpoint). Checks key size, signature algorithm, validity period, SANs, CT, EKU, and Basic Constraints against CA/B Forum standards. |\n| `verify_key_match` | Verify that a private key matches a certificate (PEM file or HTTPS endpoint). |\n| `convert_pfx_to_pem` | Convert PKCS12/PFX to separate PEM files (cert, key, CA chain). |\n| `convert_pem_to_pfx` | Convert PEM certificate + key to PKCS12/PFX file. |\n| `create_keystore` | Create a PKCS12 keystore from PEM cert + key (Java-compatible). |\n| `create_truststore` | Create a PKCS12 truststore from CA certificate PEM files. |\n\n### Configuration\n\n#### Claude Code / Kiro / Kiro CLI\n\nThese tools use the same `mcpServers` configuration format. Create the config file at the appropriate location:\n\n| Tool | Project config | Global config |\n|------|---------------|---------------|\n| Claude Code | `.mcp.json` | `~/.claude/settings/mcp.json` |\n| Kiro (IDE) | `.kiro/settings/mcp.json` | `~/.kiro/settings/mcp.json` |\n| Kiro CLI | `.kiro/settings/mcp.json` | `~/.kiro/settings/mcp.json` |\n\n```json\n{\n  \"mcpServers\": {\n    \"dcert\": {\n      \"type\": \"stdio\",\n      \"command\": \"dcert-mcp\"\n    }\n  }\n}\n```\n\nOr add via Claude Code CLI:\n\n```bash\nclaude mcp add dcert -- dcert-mcp\n```\n\n#### VS Code (GitHub Copilot)\n\nCreate `.vscode/mcp.json` in your workspace:\n\n```json\n{\n  \"servers\": {\n    \"dcert\": {\n      \"type\": \"stdio\",\n      \"command\": \"dcert-mcp\"\n    }\n  }\n}\n```\n\n#### JetBrains IDEs\n\nFor JetBrains IDEs **2025.2+**: Go to **Settings \u003e Tools \u003e AI Assistant \u003e Model Context Protocol (MCP)**, click **+**, choose **\"As JSON\"**, and paste:\n\n```json\n{\n  \"mcpServers\": {\n    \"dcert\": {\n      \"type\": \"stdio\",\n      \"command\": \"dcert-mcp\"\n    }\n  }\n}\n```\n\nFor earlier versions, install the [MCP Server plugin](https://plugins.jetbrains.com/plugin/26071-mcp-server) first.\n\n#### Docker-based MCP\n\nUse the Docker image if `dcert-mcp` is not installed locally:\n\n```json\n{\n  \"mcpServers\": {\n    \"dcert\": {\n      \"type\": \"stdio\",\n      \"command\": \"docker\",\n      \"args\": [\"run\", \"--rm\", \"-i\", \"--entrypoint\", \"dcert-mcp\", \"ghcr.io/scgis-wales/dcert:main\"]\n    }\n  }\n}\n```\n\n#### Custom binary path\n\nIf `dcert-mcp` is not on your `PATH`, specify the full path. You can also set `DCERT_PATH` to tell the MCP server where to find the `dcert` CLI:\n\n```json\n{\n  \"mcpServers\": {\n    \"dcert\": {\n      \"type\": \"stdio\",\n      \"command\": \"/usr/local/bin/dcert-mcp\",\n      \"env\": {\n        \"DCERT_PATH\": \"/usr/local/bin/dcert\"\n      }\n    }\n  }\n}\n```\n\n### Proxy and Timeout Configuration\n\nIn corporate environments behind forward proxies, `dcert-mcp` inherits proxy settings from the environment. The subprocess (`dcert`) automatically receives all parent environment variables including proxy and SSL settings.\n\n#### Proxy environment variables\n\n| Variable | Description |\n|----------|-------------|\n| `HTTPS_PROXY` / `https_proxy` | Forward proxy URL for HTTPS connections |\n| `HTTP_PROXY` / `http_proxy` | Forward proxy URL for HTTP connections (fallback for HTTPS) |\n| `NO_PROXY` / `no_proxy` | Comma-separated list of hosts to bypass the proxy |\n| `SSL_CERT_FILE` | Custom CA certificate file for proxy TLS interception |\n| `SSL_CERT_DIR` | Custom CA certificate directory |\n\nExample configuration with a corporate proxy:\n\n```json\n{\n  \"mcpServers\": {\n    \"dcert\": {\n      \"type\": \"stdio\",\n      \"command\": \"dcert-mcp\",\n      \"env\": {\n        \"HTTPS_PROXY\": \"http://proxy.corp.com:8080\",\n        \"NO_PROXY\": \"localhost,127.0.0.1,.internal.corp.com\",\n        \"SSL_CERT_FILE\": \"/etc/ssl/certs/corporate-ca.pem\"\n      }\n    }\n  }\n}\n```\n\n#### Timeout settings\n\n`dcert-mcp` supports configurable timeouts via CLI flags or environment variables:\n\n| Setting | CLI flag | Environment variable | Default | Description |\n|---------|----------|---------------------|---------|-------------|\n| Subprocess timeout | `--timeout` | `DCERT_MCP_TIMEOUT` | 60s | Max time for a single dcert invocation |\n| Connection timeout | `--connection-timeout` | `DCERT_MCP_CONNECTION_TIMEOUT` | 10s | TCP connection timeout (passed to dcert) |\n| Read timeout | `--read-timeout` | `DCERT_MCP_READ_TIMEOUT` | 5s | Response read timeout (passed to dcert) |\n\nExample with extended timeouts for slow networks:\n\n```json\n{\n  \"mcpServers\": {\n    \"dcert\": {\n      \"type\": \"stdio\",\n      \"command\": \"dcert-mcp\",\n      \"env\": {\n        \"DCERT_MCP_TIMEOUT\": \"120\",\n        \"DCERT_MCP_CONNECTION_TIMEOUT\": \"30\",\n        \"DCERT_MCP_READ_TIMEOUT\": \"15\"\n      }\n    }\n  }\n}\n```\n\n### Troubleshooting\n\n#### Startup diagnostics\n\n`dcert-mcp` logs diagnostic information to stderr at startup. In MCP mode, stderr is separate from the protocol channel (which uses stdio), so these logs are visible in your IDE's MCP server output or logs:\n\n```\n[dcert-mcp] v3.0.12\n[dcert-mcp] dcert binary: /usr/local/bin/dcert\n[dcert-mcp] subprocess timeout: 60s\n[dcert-mcp] connection timeout: 10s (--timeout)\n[dcert-mcp] read timeout: 5s (--read-timeout)\n[dcert-mcp] HTTPS proxy: http://proxy.corp.com:8080\n[dcert-mcp] HTTP proxy: (none)\n[dcert-mcp] NO_PROXY: localhost,127.0.0.1\n```\n\nProxy URLs are logged with passwords masked (shown as `****`).\n\n#### Common issues\n\n**MCP server hangs or times out silently**\n\nThis often happens behind corporate proxies. Check:\n\n1. Verify proxy settings are passed to `dcert-mcp` via the MCP config `env` block\n2. Check the startup diagnostics show the expected proxy URL\n3. Increase `DCERT_MCP_TIMEOUT` if the proxy is slow\n4. If the target is internal, add it to `NO_PROXY`\n5. If TLS interception is used, set `SSL_CERT_FILE` to the corporate CA bundle\n\n**dcert binary not found**\n\nIf the startup log shows a warning about the dcert binary not being found:\n\n1. Ensure `dcert` is on your `PATH`, or\n2. Set `DCERT_PATH` to the full path in the MCP config `env` block\n\n**Timeout errors with diagnostic hints**\n\nWhen a subprocess times out, `dcert-mcp` produces actionable error messages that include:\n- The timeout duration\n- Detected proxy configuration\n- Suggestions for adjusting timeout environment variables\n- Hints about DNS, connectivity, or proxy issues\n\n### HTTP Transport Mode\n\nFor remote or multi-user deployments, `dcert-mcp` can run as an HTTP server:\n\n```bash\n# Start in HTTP mode (no auth)\ndcert-mcp --mode http --addr 0.0.0.0:3000\n\n# With OIDC/OAuth2 authentication\nDCERT_MCP_OIDC_ISSUER=\"https://login.example.com/v2.0\" \\\nDCERT_MCP_OIDC_AUDIENCE=\"api://dcert-mcp\" \\\ndcert-mcp --mode http --addr 0.0.0.0:3000\n\n# With static bearer token (simpler deployments)\nDCERT_MCP_AUTH_TOKEN=\"my-secret-token\" \\\ndcert-mcp --mode http\n```\n\nThe HTTP server exposes:\n- `GET /health` — health check endpoint\n- `POST /mcp` — JSON-RPC endpoint for MCP tool calls\n\n#### Authentication (OIDC/OAuth2)\n\nWhen running in HTTP mode, `dcert-mcp` supports OIDC/OAuth2 JWT authentication following [MCP Security Best Practices](https://modelcontextprotocol.io/specification/2024-11-05/security). Authentication is resolved in priority order:\n\n1. **OIDC/OAuth2** — if `DCERT_MCP_OIDC_ISSUER` is set (recommended for production)\n2. **Static bearer token** — if only `DCERT_MCP_AUTH_TOKEN` is set\n3. **No auth** — if neither is configured\n\nOIDC tokens are validated against JWKS (JSON Web Key Sets) with automatic key rotation. Validated tokens are cached in-memory with a configurable sliding window TTL.\n\n#### On-Behalf-Of (OBO) Token Exchange\n\nFor downstream API calls that require user context, `dcert-mcp` supports the OBO token exchange flow:\n\n- User tokens are **never forwarded** to downstream APIs\n- OBO exchange acquires a new token scoped to the downstream resource\n- Classified error handling with actionable guidance for each failure mode\n\n#### Authentication Environment Variables\n\n| Variable | Description |\n|----------|-------------|\n| `DCERT_MCP_OIDC_ISSUER` | OIDC issuer URL (enables OIDC mode) |\n| `DCERT_MCP_OIDC_AUDIENCE` | Expected audience claim (required with OIDC) |\n| `DCERT_MCP_OIDC_JWKS_URL` | JWKS URL (auto-discovered from issuer if omitted) |\n| `DCERT_MCP_REQUIRED_SCOPES` | Comma-separated required OAuth2 scopes |\n| `DCERT_MCP_REQUIRED_ROLES` | Comma-separated required app roles |\n| `DCERT_MCP_ALLOWED_CLIENTS` | Comma-separated allowed client app IDs |\n| `DCERT_MCP_SESSION_TTL` | Session cache inactivity TTL in seconds (default: 300) |\n| `DCERT_MCP_AUTH_TOKEN` | Static bearer token (lower priority than OIDC) |\n| `DCERT_MCP_OBO_TOKEN_URL` | OBO token exchange endpoint |\n| `DCERT_MCP_OBO_CLIENT_ID` | OBO client application ID |\n| `DCERT_MCP_OBO_CLIENT_SECRET` | OBO client secret |\n\nSee [SECURITY.md](SECURITY.md) for full security architecture documentation.\n\n---\n\n## Features by Topic\n\n### Certificate Analysis\n\nDecode X.509 certificates from PEM files, HTTPS endpoints, bare hostnames, or piped stdin: subject, issuer, serial number, validity window, SANs, expiry status. Reads PEM data automatically when piped (e.g. `cat cert.pem | dcert`).\n\n### Certificate Extensions and Fingerprints\n\nSHA-256 fingerprints (`--fingerprint`), key usage, extended key usage, basic constraints, authority info access, signature algorithm, public key info, SCT count (`--extensions`).\n\n### TLS Debugging\n\nProtocol version, cipher suite, ALPN negotiation, certificate transparency, verification result, and per-certificate chain validation detail. Network latency measurements for DNS resolution, TCP connect (Layer 4), and TLS+HTTP (Layer 7). Enable `--debug` for full OSI-layer diagnostics.\n\n### Mutual TLS (mTLS)\n\nClient certificate authentication via PEM (`--client-cert` + `--client-key`) or PKCS12/PFX (`--pkcs12` + `--cert-password`). Custom CA bundle support (`--ca-cert`) for corporate/internal PKI.\n\n### CSR Creation \u0026 Validation\n\nCreate PKCS#10 Certificate Signing Requests with guided interactive mode or CLI flags (`dcert csr create`). Supports RSA 4096 (default), RSA 2048, ECDSA P-256 (recommended), ECDSA P-384, and Ed25519 (modern EdDSA). Optional AES-256-CBC key encryption. Validate existing CSRs for compliance with CA/B Forum, DigiCert, and X9 standards (`dcert csr validate`). OU metadata identifiers (e.g., `AppId:my-service`) supported for internal PKI.\n\n### Certificate Compliance\n\nRun compliance checks against CA/B Forum Baseline Requirements, DigiCert, and X9 standards (`--compliance`). Checks key size, signature algorithm (SHA-256+ required), validity period (398-day maximum), Subject Alternative Names, Certificate Transparency (SCTs), Extended Key Usage, and Basic Constraints. Returns findings with severity levels (Error, Warning, Info) and an overall COMPLIANT/NON-COMPLIANT status. Available in pretty, JSON, and YAML formats.\n\n### Key-Certificate Matching\n\nVerify private key matches a certificate (`dcert verify-key`). Supports RSA and EC keys against PEM files or live HTTPS endpoints. Auto-discovers matching `.crt`/`.pem` + `.key` pairs in a directory when run without arguments.\n\n### PFX/PEM Conversion\n\nConvert PKCS12/PFX to separate PEM files or bundle PEM cert + key into PFX (`dcert convert pfx-to-pem`, `dcert convert pem-to-pfx`).\n\n### Java KeyStore and TrustStore\n\nCreate PKCS12 keystores and truststores compatible with Java JDK 9+ (`dcert convert create-keystore`, `dcert convert create-truststore`).\n\n### OCSP Revocation Checking\n\nQuery the certificate's OCSP responder to verify revocation status (`--check-revocation`).\n\n### Expiry Monitoring\n\nConfigurable threshold warnings (`--expiry-warn N`) with machine-readable exit codes. Continuous monitoring with `--watch`.\n\n### Certificate Comparison\n\nSide-by-side diff of certificates between two targets (`--diff`).\n\n### Certificate Export\n\nSave fetched certificate chains as PEM files (`--export-pem`), with optional filtering of expired certificates (`--exclude-expired`).\n\n### Vault PKI Integration\n\nIssue, sign, revoke, list, and renew TLS certificates via HashiCorp Vault's PKI Secrets Engine (`dcert vault`). Store and validate certificates in Vault KV v1 or v2 (`--kv-version`). Interactive wizard mode for guided certificate issuance. Full chain assembly from Vault root and intermediate CAs. Export certificate lists to JSON, CSV, or Excel (`.xlsx`). SAN and IP SAN support across all certificate operations. Role inference from Vault token policies. Clear, actionable permission error messages with Vault policy hints.\n\n---\n\n## Use Cases\n\n### DevOps \u0026 CI/CD\n\n```bash\n# Gate deployments on certificate health\ndcert https://your-api.com --expiry-warn 14\n\n# Check multiple endpoints\ndcert https://api.example.com https://www.example.com https://admin.example.com\n\n# Continuous monitoring\ndcert --watch 300 https://your-api.com\n```\n\n### Security Auditing\n\n```bash\n# Enforce TLS 1.3 only\ndcert --min-tls 1.3 https://target.com\n\n# Full audit with extensions, fingerprints, and revocation\ndcert https://site.com --fingerprint --extensions --check-revocation\n\n# Compliance audit against CA/B Forum Baseline Requirements\ndcert https://site.com --compliance\n\n# Test specific cipher suites\ndcert --cipher-list \"ECDHE+AESGCM\" --max-tls 1.2 https://target.com\n```\n\n### CSR Management\n\n```bash\n# Create a CSR for a new service\ndcert csr create --cn api.example.com --org \"My Corp\" --country GB --san DNS:api.example.com\n\n# Create with ECDSA P-256 for modern deployments\ndcert csr create --cn api.example.com --key-algo ecdsa-p256\n\n# Create with Ed25519 (modern EdDSA, compact signatures)\ndcert csr create --cn api.example.com --key-algo ed25519\n\n# Validate before submitting to CA\ndcert csr validate api-example-com.csr --format json\n\n# Internal PKI with metadata identifiers\ndcert csr create --cn app.internal.corp --ou \"AppId:svc-123\" --ou \"Env:prod\"\n```\n\n### Vault PKI Automation\n\n```bash\n# Issue a certificate from Vault PKI and store in KV\ndcert vault issue --cn www.example.com --role web-server \\\n  --san \"DNS:*.example.com\" --store-path secret/certs/www-example-com\n\n# Renew a certificate stored in Vault KV\ndcert vault renew secret/certs/www-example-com --role web-server\n\n# Validate certificates stored in Vault KV\ndcert vault validate secret/certs/www-example-com\n\n# Audit all issued certificates\ndcert vault list --show-details --export audit.xlsx\n\n# Sign a CSR through Vault PKI\ndcert vault sign --csr-file server.csr --role web-server --ttl 2160h\n```\n\n### Certificate Management\n\n```bash\n# Convert PFX for web server deployment\ndcert convert pfx-to-pem server.pfx --password secret --output-dir /etc/ssl\n\n# Prepare Java keystore\ndcert convert create-keystore --cert server.pem --key server-key.pem --output keystore.p12 --password changeit\n\n# Verify key matches certificate before deployment\ndcert verify-key server.pem --key server-key.pem\n\n# Verify all cert/key pairs in a directory\ndcert verify-key --dir /etc/ssl/certs\n\n# Compare staging vs production certificates\ndcert --diff https://staging.example.com https://prod.example.com\n\n# Export and backup certificate chains\nfor domain in google.com github.com; do\n  dcert \"https://$domain\" --export-pem \"${domain}-chain.pem\"\ndone\n```\n\n---\n\n## Python Package\n\nA Python wrapper is available on PyPI, providing a FastMCP proxy around the `dcert-mcp` Rust binary. The Rust binary is **automatically downloaded** on first use with SHA256 checksum verification.\n\n```bash\npip install dcert\n```\n\n### Quick Start\n\n```python\nfrom dcert import create_server\n\nserver = create_server()\nserver.run()  # stdio mode (default)\n```\n\n### CLI\n\n```bash\n# stdio mode (default, for MCP clients like Claude Code)\ndcert-python\n\n# HTTP mode\ndcert-python --transport http --host 0.0.0.0 --port 8080\n\n# Pre-download binary\ndcert-python --setup\n```\n\n### Binary Discovery\n\nThe Python package locates the `dcert-mcp` binary in this order:\n\n1. `DCERT_MCP_BINARY` environment variable\n2. Bundled binary in the package `bin/` directory\n3. Auto-download from GitHub Releases (with SHA256 checksum verification)\n4. `dcert-mcp` on `PATH`\n\nSee the [Python package README](python/README.md) for full documentation.\n\n---\n\n## Development\n\n```bash\ncargo fmt --all\ncargo clippy --all-targets --all-features -- -D warnings\ncargo test\ncargo build --release\n```\n\n## License\n\nMIT. See [LICENSE](LICENSE).\n\n## Acknowledgements\n\n- X.509 parsing by [x509-parser]\n- CLI framework by [clap]\n- Terminal colors by [colored]\n- TLS connections and OCSP by [openssl]\n- YAML serialization by [serde_yaml_ng]\n- Signal handling by [ctrlc]\n- MCP server by [rmcp]\n\n[x509-parser]: https://crates.io/crates/x509-parser\n[clap]: https://crates.io/crates/clap\n[colored]: https://crates.io/crates/colored\n[openssl]: https://crates.io/crates/openssl\n[serde_yaml_ng]: https://crates.io/crates/serde_yaml_ng\n[ctrlc]: https://crates.io/crates/ctrlc\n[rmcp]: https://crates.io/crates/rmcp\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fscgis-wales%2Fdcert","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fscgis-wales%2Fdcert","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fscgis-wales%2Fdcert/lists"}