< Summary - Kestrun — Combined Coverage

Information
Class: Public.Certificate.New-KrPrivateKeyJwt
Assembly: Kestrun.PowerShell.Public
File(s): /home/runner/work/Kestrun/Kestrun/src/PowerShell/Kestrun/Public/Certificate/New-KrPrivateKeyJwt.ps1
Tag: Kestrun/Kestrun@0d738bf294e6281b936d031e1979d928007495ff
Line coverage
0%
Covered lines: 0
Uncovered lines: 21
Coverable lines: 21
Total lines: 140
Line coverage: 0%
Branch coverage
N/A
Covered branches: 0
Total branches: 0
Branch coverage: N/A
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Coverage history

Coverage history 0 25 50 75 100 11/19/2025 - 02:25:56 Line coverage: 0% (0/21) Total lines: 140 Tag: Kestrun/Kestrun@98ff905e5605a920343154665980a71211a03c6d

Metrics

File(s)

/home/runner/work/Kestrun/Kestrun/src/PowerShell/Kestrun/Public/Certificate/New-KrPrivateKeyJwt.ps1

#LineLine coverage
 1<#
 2    .SYNOPSIS
 3        Builds a Private Key JWT (client assertion) for OAuth2/OIDC client authentication.
 4    .DESCRIPTION
 5        This function generates a signed JWT suitable for private_key_jwt client authentication
 6        using either an X509 certificate or a JWK JSON string as the signing key.
 7
 8        It uses Kestrun.Certificates.CertificateManager.BuildPrivateKeyJwt[FromJwkJson]
 9        under the hood, with:
 10          - iss = client_id
 11          - sub = client_id
 12          - aud = token endpoint
 13          - short lifetime (about 2 minutes) and a random jti.
 14    .PARAMETER Certificate
 15        The X509Certificate2 object whose private key will be used to sign the JWT.
 16    .PARAMETER Path
 17        Path to a certificate on disk. This is resolved via Resolve-KrPath and imported
 18        using [Kestrun.Certificates.CertificateManager]::Import().
 19    .PARAMETER JwkJson
 20        A JWK JSON string representing the key (typically an RSA private key JWK).
 21    .PARAMETER ClientId
 22        The client identifier; used as both issuer (iss) and subject (sub) in the JWT.
 23    .PARAMETER TokenEndpoint
 24        The token endpoint URL; used as the audience (aud) in the JWT.
 25    .PARAMETER Authority
 26        The authority (issuer) URL; used to discover the token endpoint via OIDC discovery.
 27    .PARAMETER WhatIf
 28        Shows what would happen if the command runs. The command is not run.
 29    .PARAMETER Confirm
 30        Prompts you for confirmation before running the command. The command is not run unless you respond
 31        affirmatively.
 32    .OUTPUTS
 33        [string] – the signed JWT (client assertion).
 34    .EXAMPLE
 35        $cert | New-KrPrivateKeyJwt -ClientId 'my-client' -TokenEndpoint 'https://idp.example.com/oauth2/token'
 36
 37        Builds a private_key_jwt client assertion using the certificate from the pipeline.
 38    .EXAMPLE
 39        New-KrPrivateKeyJwt -Path './certs/client.pfx' -ClientId 'my-client' `
 40            -TokenEndpoint 'https://idp.example.com/oauth2/token'
 41
 42        Imports the certificate from disk and generates a private_key_jwt.
 43    .EXAMPLE
 44        $jwk = ConvertTo-KrJwkJson -Certificate $cert -IncludePrivateParameters
 45        New-KrPrivateKeyJwt -JwkJson $jwk -ClientId 'my-client' `
 46            -TokenEndpoint 'https://idp.example.com/oauth2/token'
 47
 48        Generates a private_key_jwt using a private RSA JWK JSON string.
 49    .EXAMPLE
 50        $cert | New-KrPrivateKeyJwt `
 51            -ClientId 'interactive.confidential' `
 52            -Authority 'https://demo.duendesoftware.com'
 53
 54        Uses discovery to resolve the token_endpoint from the authority.
 55    .NOTES
 56        Requires the Kestrun module and the Kestrun.Certificates assembly to be loaded.
 57#>
 58function New-KrPrivateKeyJwt {
 59    [KestrunRuntimeApi('Everywhere')]
 60    [CmdletBinding(SupportsShouldProcess = $true, DefaultParameterSetName = 'ByCertificate_Authority')]
 61    [OutputType([string])]
 62    param(
 63        [Parameter(Mandatory = $true, ValueFromPipeline = $true, ParameterSetName = 'ByCertificate_Authority')]
 64        [Parameter(Mandatory = $true, ValueFromPipeline = $true, ParameterSetName = 'ByCertificate_EndPoint')]
 65        [System.Security.Cryptography.X509Certificates.X509Certificate2]
 66        $Certificate,
 67
 68        [Parameter(Mandatory = $true, ParameterSetName = 'ByJwkJson_Authority')]
 69        [Parameter(Mandatory = $true, ParameterSetName = 'ByJwkJson_EndPoint')]
 70        [string]
 71        $JwkJson,
 72
 73        [Parameter(Mandatory = $true)]
 74        [string]
 75        $ClientId,
 76
 77
 78        [Parameter(Mandatory = $true, ParameterSetName = 'ByJwkJson_EndPoint')]
 79        [Parameter(Mandatory = $true, ParameterSetName = 'ByCertificate_EndPoint')]
 80        [string]
 81        $TokenEndpoint,
 82
 83        [Parameter(Mandatory = $true, ParameterSetName = 'ByJwkJson_Authority')]
 84        [Parameter(Mandatory = $true, ParameterSetName = 'ByCertificate_Authority')]
 85        [string]
 86        $Authority
 87    )
 88    process {
 089        if (-not $PSCmdlet.ShouldProcess("ClientId '$ClientId' to audience '$TokenEndpoint'", 'Generate private_key_jwt'
 90            return
 91        }
 092        $ResolvedTokenEndpoint = if ( -not ([string]::IsNullOrWhiteSpace($Authority))) {
 093            $discoUrl = ($Authority.TrimEnd('/')) + '/.well-known/openid-configuration'
 094            Write-KrLog -Level Debug -Message 'Discovering token endpoint from authority: {authority}' -Values $Authorit
 95
 96            try {
 097                $meta = Invoke-RestMethod -Uri $discoUrl -Method Get
 98            } catch {
 099                throw "Failed to fetch OIDC discovery document from '$discoUrl': $($_.Exception.Message)"
 100            }
 101
 0102            if (-not $meta.token_endpoint) {
 0103                throw "OIDC discovery document from '$discoUrl' does not contain a token_endpoint."
 104            }
 105
 0106            Write-KrLog -Level Debug -Message 'Discovered token endpoint: {tokenEndpoint}' -Values $meta.token_endpoint
 0107            [string]$meta.token_endpoint
 108        } else {
 0109            $TokenEndpoint
 110        }
 111
 0112        if (-not [string]::IsNullOrWhiteSpace($JwkJson)) {
 113
 0114            Write-KrLog -Level Verbose -Message "Building private_key_jwt from JWK JSON for client '$ClientId'"
 0115            return [Kestrun.Certificates.CertificateManager]::BuildPrivateKeyJwtFromJwkJson(
 116                $JwkJson,
 117                $ClientId,
 118                $ResolvedTokenEndpoint
 119            )
 120        }
 121
 122        # ByCertificate / ByPath
 0123        $cert = $Certificate
 124
 0125        if ($null -eq $cert) {
 0126            throw 'Failed to obtain certificate instance.'
 127        }
 128
 0129        if (-not $cert.HasPrivateKey) {
 0130            throw 'Certificate does not contain a private key; cannot build a private_key_jwt.'
 131        }
 132
 0133        Write-KrLog -Level Verbose -Message "Building private_key_jwt from certificate for client '$ClientId'"
 0134        return [Kestrun.Certificates.CertificateManager]::BuildPrivateKeyJwt(
 135            $cert,
 136            $ClientId,
 137            $TokenEndpoint
 138        )
 139    }
 140}

Methods/Properties

New-KrPrivateKeyJwt()