Inbound-API bearer credentials are no longer persisted in plaintext. ApiKey now holds a KeyHash (peppered HMAC-SHA256); the key is shown once at creation and only its hash is stored. Lookup and validation hash the presented candidate. Cross-module: Commons (ApiKey, ApiKeyHasher), ConfigurationDatabase (mapping + HashApiKeyValue migration), InboundAPI (ApiKeyValidator), ManagementService (key creation), CentralUI (ApiKeys.razor). Existing keys must be re-issued.
35 lines
1.6 KiB
C#
35 lines
1.6 KiB
C#
namespace ScadaLink.InboundAPI;
|
|
|
|
public class InboundApiOptions
|
|
{
|
|
/// <summary>
|
|
/// Default cap on the inbound API request body, in bytes (InboundAPI-006).
|
|
/// </summary>
|
|
public const long DefaultMaxRequestBodyBytes = 1L * 1024 * 1024; // 1 MiB
|
|
|
|
public TimeSpan DefaultMethodTimeout { get; set; } = TimeSpan.FromSeconds(30);
|
|
|
|
/// <summary>
|
|
/// InboundAPI-006: maximum accepted request body size for <c>POST /api/{methodName}</c>.
|
|
/// Requests whose body exceeds this are rejected with HTTP 413 before being
|
|
/// buffered into a <see cref="System.Text.Json.JsonDocument"/>. The inbound API
|
|
/// has no rate limiting (a deliberate design choice), so an explicit, modest cap
|
|
/// bounds per-request allocations.
|
|
/// </summary>
|
|
public long MaxRequestBodyBytes { get; set; } = DefaultMaxRequestBodyBytes;
|
|
|
|
/// <summary>
|
|
/// ConfigurationDatabase-012: server-side HMAC pepper used to hash inbound-API
|
|
/// bearer credentials. API keys are persisted as a deterministic keyed hash, never
|
|
/// as plaintext; this pepper is the HMAC key that binds every hash to this
|
|
/// deployment, so a stolen configuration database is not directly exploitable.
|
|
/// <para>
|
|
/// This is a secret: supply a strong, random value via configuration or a secret
|
|
/// store, never hard-coded. It must be present and at least
|
|
/// <see cref="ScadaLink.Commons.Types.InboundApi.ApiKeyHasher.MinimumPepperLength"/>
|
|
/// characters — <c>AddInboundAPI</c> fails fast otherwise.
|
|
/// </para>
|
|
/// </summary>
|
|
public string ApiKeyPepper { get; set; } = string.Empty;
|
|
}
|