< Summary - Heimdall API

Information
Class: ArturRios.Heimdall.WebApi.Controllers.SigningKeysController
Assembly: ArturRios.Heimdall.WebApi
File(s): /home/ci/agent/workspace/heimdall-api-docs_main/app/src/Presentation/ArturRios.Heimdall.WebApi/Controllers/SigningKeysController.cs
Line coverage
100%
Covered lines: 3
Uncovered lines: 0
Coverable lines: 3
Total lines: 43
Line coverage: 100%
Branch coverage
N/A
Covered branches: 0
Total branches: 0
Branch coverage: N/A
Method coverage
100%
Covered methods: 2
Fully covered methods: 2
Total methods: 2
Method coverage: 100%
Full method coverage: 100%

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
KeySet()100%11100%

File(s)

/home/ci/agent/workspace/heimdall-api-docs_main/app/src/Presentation/ArturRios.Heimdall.WebApi/Controllers/SigningKeysController.cs

#LineLine coverage
 1using ArturRios.Heimdall.WebApi.Documentation;
 2using ArturRios.Heimdall.WebApi.Security;
 3using ArturRios.Util.WebApi.Security.Attributes;
 4using Microsoft.AspNetCore.Mvc;
 5using Microsoft.AspNetCore.RateLimiting;
 6
 7namespace ArturRios.Heimdall.WebApi.Controllers;
 8
 9/// <summary>
 10///     The public halves of Heimdall's signing keys (NFR-31, Threat Model TH-43): the key set every
 11///     consumer verifies Heimdall's ES256 tokens with.
 12/// </summary>
 13/// <remarks>
 14///     Outside <c>api/</c>, at the path RFC 8615 reserves for it, because consumers fetch the key set
 15///     from the API's own host or the edge network, never through the web UI's host — see
 16///     <c>OpenApiContractTests</c>.
 17/// </remarks>
 18[Route(".well-known")]
 1219public class SigningKeysController(TokenSigningKeys keys) : Controller
 20{
 21    /// <summary>
 22    ///     The public keys Heimdall's tokens are signed with, as an RFC 7517 JSON Web Key Set: the
 23    ///     current key first, then the previous one while a rotation is in progress. Public — no
 24    ///     authentication required, and any bearer token on the request is ignored.
 25    /// </summary>
 26    /// <remarks>
 27    ///     The body is the key set itself, not the <c>DataOutput</c> envelope every other endpoint
 28    ///     answers, so a standard JWKS reader can consume it unchanged. It carries no private member.
 29    ///     Cacheable for five minutes. Limited to ten requests a minute per address, a budget shared
 30    ///     with the other anonymous credential endpoints; a rejection answers 429 "Too many requests."
 31    ///     with a <c>Retry-After</c> header.
 32    /// </remarks>
 33    [HttpGet("jwks.json")]
 34    [AllowAnonymous]
 35    [EnableRateLimiting(RateLimitingConfiguration.AuthEndpointRateLimitPolicy)]
 36    [ProducesResponseType<JsonWebKeySetDocument>(StatusCodes.Status200OK, "application/json")]
 37    public ContentResult KeySet()
 38    {
 1239        Response.Headers.CacheControl = "public, max-age=300";
 40
 1241        return Content(keys.JwksJson, "application/json");
 42    }
 43}