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.ceror.pemfile. -
-Certificatewith-CertificatePassword: Path to a.pfxfile and its password. -
-Certificatewith-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\Myby name.
-
-
X.509 Certificates:
-
-X509Certificate: Provides a certificate object of typeX509Certificate2. -
-SelfSigned: Generates a quick self-signedX509Certificatefor 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::1localhost- 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
.pfxor.pemfile 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 2048This 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
.csrfile 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-Nullto 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" -IncludePrivateKeyA 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
$purposesWhen 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-NullRefer 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 (
NotBeforeandNotAfter). - ✅ 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.