π PCL - Policy-based Certificate Linter
A flexible X.509 certificate linter that validates certificates against configurable YAML-based policies. Ensure compliance with RFC 5280, organizational standards, or industry best practices.
go install github.com/cavoq/PCL/cmd/pcl@latest
pcl --policy < path> --cert < path> [--crl < path> ] [--ocsp < path> ] [--output text| json| yaml]
By default, only failed rules are shown. Use -v to include passed rules and -vv to include skipped rules.
You can also fetch a TLS certificate chain from HTTPS URLs:
pcl --policy < path> --cert-url https://example.test --cert-url-timeout 10s --cert-url-save-dir ./downloads
π Policy Configuration
Policies are YAML files defining validation rules with a simple declarative syntax.
id : rfc5280
rules :
- id : version-v3
target : certificate.version
operator : eq
operands : [3]
severity : error
- id : signature-algorithm-secure
target : certificate.signatureAlgorithm.algorithm
operator : in
operands :
- SHA256-RSA
- SHA384-RSA
- ECDSA-SHA256
severity : error
# Conditional rule using "when" clause
- id : rsa-key-size-minimum
when :
target : certificate.subjectPublicKeyInfo.algorithm
operator : eq
operands : [RSA]
target : certificate.subjectPublicKeyInfo.publicKey.keySize
operator : gte
operands : [2048]
severity : error
- id : ca-basic-constraints
target : certificate.basicConstraints.cA
operator : eq
operands : [true]
severity : error
appliesTo : [root, intermediate]
# Optional document reference (used by text output)
- id : key-usage-leaf
reference : RFC5280 4.2.1.3
target : certificate.keyUsage
operator : keyUsageLeaf
severity : error
ποΈ Supported Policies
RFC 5280 - Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile
Operator
Description
eq
Equality check
neq
Not equal check
gt, gte
Greater than (or equal)
lt, lte
Less than (or equal)
in
Value in allowed list
notIn
Value not in disallowed list
contains
String/array contains value
matches
Compare two field paths for equality
Presence & Value Operators
Operator
Description
present
Field existence check
absent
Field does not exist
isEmpty, notEmpty
Value emptiness check
positive
Value is a positive number
odd
Value is an odd number (for RSA exponent validation)
maxLength, minLength
String/array length constraints
regex, notRegex
Regular expression pattern matching
Operator
Description
before
Date is before current time
after
Date is after current time
validityOrderCorrect
Validates notBefore < notAfter
validityDays
Certificate validity period check
Operator
Description
isCritical, notCritical
Extension criticality check
noUnknownCriticalExtensions
No unhandled critical extensions
Certificate Chain Operators
Operator
Description
signatureValid
Cryptographic signature verification
signatureAlgorithmMatchesTBS
Signature algorithm matches TBS certificate
issuedBy
Issuer DN matches issuer's subject DN
akiMatchesSki
Authority Key ID matches issuer's Subject Key ID
pathLenValid
Path length constraint validation
serialNumberUnique
Serial number uniqueness in chain
Key Usage & Constraints Operators
Operator
Description
sanRequiredIfEmptySubject
SAN required when subject is empty
keyUsageCA, keyUsageLeaf
Key usage validation by cert type
ekuContains, ekuNotContains
Extended key usage checks
ekuServerAuth, ekuClientAuth
TLS authentication EKU checks
noUniqueIdentifiers
Absence of issuer/subject unique IDs
Operator
Description
crlValid
CRL is within thisUpdate/nextUpdate window
crlNotExpired
CRL nextUpdate is in the future
crlSignedBy
CRL signature verification against chain
notRevoked
Certificate not in CRL revoked list
Operator
Description
ocspValid
OCSP response is within validity window and signature is valid
notRevokedOCSP
Certificate not revoked according to OCSP
ocspGood
Certificate has explicit Good status in OCSP response
Path Validation Operators
Operator
Description
nameConstraintsValid
Validates names against permitted/excluded subtrees from chain
certificatePolicyValid
Validates policy OIDs through chain with mappings and constraints
Rules can include a when clause to apply only when certain conditions are met:
- id : rsa-exponent-valid
when :
target : certificate.subjectPublicKeyInfo.algorithm
operator : eq
operands : [RSA]
target : certificate.subjectPublicKeyInfo.publicKey.exponent
operator : odd
severity : error
This rule only validates RSA exponent when the certificate uses RSA. If the condition is not met, the rule is skipped.
Certificate Chain Support
PCL automatically builds and validates certificate chains, applying rules based on certificate position:
leaf: End-entity certificates
intermediate: CA certificates in the chain
root: Self-signed root CA certificates
Use appliesTo in rules to target specific certificate types.
go build -o pcl ./cmd/pcl
go test -v -race ./...
golangci-lint run ./...