Certificates - mdaneri/Pode GitHub Wiki
Pode has the ability to generate and bind self-signed certificates (for dev/testing), as well as the ability to bind existing certificates for HTTPS or JWT.
Pode provides multiple ways to configure HTTPS on Add-PodeEndpoint
:
-
File-based certificates:
-
-Certificate
: Path to a.cer
or.pem
file. -
-Certificate
with-CertificatePassword
: Path to a.pfx
file and its password. -
-Certificate
with-CertificateKey
: Paths to a certificate/key PEM file pair. -
-Certificate
,-CertificateKey
, and-CertificatePassword
: Paths to an encrypted PEM file pair and its password.
-
-
Windows Certificate Store:
-
-CertificateThumbprint
: Uses a certificate installed atCert:\CurrentUser\My
. -
-CertificateName
: Uses a certificate installed atCert:\CurrentUser\My
by name.
-
-
X.509 Certificates:
-
-X509Certificate
: Provides a certificate object of typeX509Certificate2
. -
-SelfSigned
: Generates a quick self-signedX509Certificate
for development.
-
-
Custom Certificate Management:
- Pode’s built-in functions allow better control over certificate creation, import, and export.
Pode provides the New-PodeSelfSignedCertificate
function for creating self-signed X.509 certificates for development and testing purposes.
- ✅ Creates a self-signed certificate for HTTPS, JWT, or other use cases.
- ✅ Supports RSA and ECDSA keys with configurable key sizes.
- ✅ Can include multiple Subject Alternative Names (SANs) (e.g.,
localhost
, IP addresses). - ✅ Allows setting certificate purposes (ServerAuth, ClientAuth, etc.).
- ✅ Provides ephemeral certificates (in-memory only, not stored on disk).
- ✅ Supports exportable certificates that can be saved for later use.
$cert = New-PodeSelfSignedCertificate -DnsName "example.com" -CertificatePurpose ServerAuth
- Creates a self-signed RSA certificate for
example.com
. - The certificate is valid for HTTPS (
ServerAuth
).
$cert = New-PodeSelfSignedCertificate -Loopback
- Automatically includes common loopback addresses:
127.0.0.1
::1
localhost
- The machine’s hostname
$cert = New-PodeSelfSignedCertificate -DnsName "test.local" -KeyType "ECDSA" -KeyLength 384
- Creates a self-signed ECDSA certificate with a 384-bit key.
$cert = New-PodeSelfSignedCertificate -DnsName "temp.local" -Ephemeral
- The private key is not stored on disk, and the certificate only exists in-memory.
$cert = New-PodeSelfSignedCertificate -DnsName "secureapp.local" -Exportable
- The certificate is exportable and can be saved as a
.pfx
or.pem
file later.
Start-PodeServer {
$cert = New-PodeSelfSignedCertificate -DnsName "example.com" -CertificatePurpose ServerAuth
Add-PodeEndpoint -Address * -Port 8443 -Protocol Https -X509Certificate $cert
}
- Creates an HTTPS endpoint using a self-signed certificate.
To generate a Certificate Signing Request (CSR) along with a private key, use the New-PodeCertificateRequest
function:
$csr = New-PodeCertificateRequest -DnsName "example.com" -CommonName "example.com" -KeyType "RSA" -KeyLength 2048
This will create a CSR file and a private key file in the current directory. You can specify additional parameters such as organization details and certificate purposes.
Once you have generated a CSR, you need to submit it to a Certificate Authority (CA) (such as Let's Encrypt, DigiCert, or a private CA) to receive a signed certificate. The process typically involves:
- Uploading or providing the
.csr
file to the CA. - Completing domain validation steps (if required).
- Receiving the signed certificate (
.cer
,.pem
, or.pfx
) from the CA. - Importing the signed certificate into Pode for use.
Example: Importing the signed certificate after receiving it from the CA:
$cert = Import-PodeCertificate -Path "C:\Certs\signed-cert.pfx" -CertificatePassword (ConvertTo-SecureString "MyPass" -AsPlainText -Force)
if (-not (Test-PodeCertificate -Certificate $cert -ErrorAction Stop)) {
throw 'Certificate not valid'
}
Alternatively, you can use:
Test-PodeCertificate -Certificate $cert -ErrorAction Stop | Out-Null
to force an exception if the certificate fails validation.
Refer to the Test-PodeCertificate
documentation for any parameter details.
Pode allows exporting certificates in various formats such as PFX and PEM. To export a certificate:
Export-PodeCertificate -Certificate $cert -FilePath "C:\Certs\mycert" -Format "PFX" -CertificatePassword (ConvertTo-SecureString "MyPass" -AsPlainText -Force)
or as a PEM file with a separate private key:
Export-PodeCertificate -Certificate $cert -FilePath "C:\Certs\mycert" -Format "PEM" -IncludePrivateKey
A certificate's purpose is defined by its Enhanced Key Usage (EKU) attributes, which specify what the certificate is allowed to be used for. Common EKU values include:
-
ServerAuth
– Used for server authentication in HTTPS. -
ClientAuth
– Used for client authentication in mutual TLS setups. -
CodeSigning
– Used for digitally signing software and scripts. -
EmailSecurity
– Used for securing email communication.
Pode can extract the EKU of a certificate to determine its intended purposes:
$purposes = Get-PodeCertificatePurpose -Certificate $cert
$purposes
When Pode validates a certificate, it ensures that the certificate’s EKU matches the expected usage. If a certificate is used for an endpoint but lacks the required EKU (e.g., using a CodeSigning
certificate for ServerAuth
), Pode will reject the certificate and fail to bind it to the endpoint.
For example, if an HTTPS endpoint is created, the certificate must include ServerAuth
:
$cert = New-PodeSelfSignedCertificate -DnsName "example.com" -CertificatePurpose ServerAuth
Start-PodeServer {
Add-PodeEndpoint -Address * -Port 8443 -Protocol Https -X509Certificate $cert
}
If the certificate lacks the correct EKU, Pode will return an error when attempting to bind it.
To import a certificate from a file or the Windows certificate store:
$cert = Import-PodeCertificate -Path "C:\Certs\mycert.pfx" -CertificatePassword (ConvertTo-SecureString "MyPass" -AsPlainText -Force)
If you import a certificate without validating it, you should then call Test-PodeCertificate
to verify that the certificate is valid:
if (-not (Test-PodeCertificate -Certificate $cert -ErrorAction Stop)) {
throw 'Certificate not valid'
}
Alternatively, you can force an exception by piping the output:
Test-PodeCertificate -Certificate $cert -ErrorAction Stop | Out-Null
Refer to the Test-PodeCertificate section below for more details on all available parameters.
Pode provides the Test-PodeCertificate
function to validate an X.509 certificate and ensure it meets security and usage requirements.
- ✅ Checks if the certificate is within its validity period (
NotBefore
andNotAfter
). - ✅ Builds the certificate chain to verify its trust.
- ✅ Supports online and offline revocation checking (OCSP/CRL).
- ✅ Allows optional enforcement of strong cryptographic algorithms.
- ✅ Provides an option to reject self-signed certificates.
- ✅ Optionally checks that the certificate’s Enhanced Key Usage (EKU) matches an ExpectedPurpose (with an optional Strict mode).
Test-PodeCertificate -Certificate $cert
- Checks if the certificate is currently valid.
- Does not check revocation status.
Test-PodeCertificate -Certificate $cert -CheckRevocation
- Uses OCSP/CRL lookup to check if the certificate is revoked.
Test-PodeCertificate -Certificate $cert -CheckRevocation -OfflineRevocation
- Uses only locally cached CRLs, making it suitable for air-gapped environments.
Test-PodeCertificate -Certificate $cert -AllowWeakAlgorithms
- Allows the use of certificates with SHA1, MD5, or RSA-1024.
Test-PodeCertificate -Certificate $cert -DenySelfSigned
- Fails validation if the certificate is self-signed.
Test-PodeCertificate -Certificate $cert -ExpectedPurpose CodeSigning -Strict
- Validates that the certificate is explicitly authorized for CodeSigning.
- In strict mode, if any unknown EKUs are present, the validation fails.
Pode supports using X.509 certificates for JWT authentication. You can specify a certificate for signing and verifying JWTs by providing -X509Certificate
when creating a bearer authentication scheme:
$cert = Import-PodeCertificate -Path "C:\Certs\jwt-signing-cert.pfx" -CertificatePassword (ConvertTo-SecureString "MyPass" -AsPlainText -Force)
Start-PodeServer {
New-PodeAuthBearerScheme `
-AsJWT `
-X509Certificate $cert |
Add-PodeAuth -Name 'JWTAuth' -Sessionless -ScriptBlock {
param($token)
# Validate and extract user details
return @{ User = $user }
}
}
Alternatively, you can use a self-signed certificate for development and testing:
Start-PodeServer {
New-PodeAuthBearerScheme `
-AsJWT `
-SelfSigned |
Add-PodeAuth -Name 'JWTAuth' -Sessionless -ScriptBlock {
param($token)
# Validate and extract user details
return @{ User = $user }
}
}
Using certificates for JWT authentication provides enhanced security by enabling asymmetric signing (RSA/ECDSA) rather than using a shared secret.