826312befe
Clears CommentChecker findings in src/ (3,280 -> 209, the remainder being false positives like PLC-5/IEEE-754/M0.0) by adding missing summaries/params/returns, normalising inheritdoc usage, and removing Gitea/review tracking IDs while keeping the rationale they annotated. Comment-only: comment-stripped sources are identical to the parent commit.
68 lines
3.3 KiB
C#
68 lines
3.3 KiB
C#
namespace ZB.MOM.WW.OtOpcUa.Configuration.Entities;
|
|
|
|
/// <summary>
|
|
/// One OPC UA data-plane API key. The OPC UA data plane is machine-to-machine, so a
|
|
/// consuming system authenticates with a key rather than an LDAP user, and the key resolves to a
|
|
/// <see cref="Principal"/> that <see cref="NodeAcl"/> rows grant permissions to.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// <para>
|
|
/// <b>One principal per key, deliberately.</b> The reason to separate keys from principals is so
|
|
/// that many keys can share one grant set and rotating a key never touches an ACL row — and that
|
|
/// holds with a single principal per key, because nothing stops two keys naming the same
|
|
/// principal. A key belonging to several principals at once (union of grants) buys little and
|
|
/// costs a join table, so it is not modelled. <c>UserAuthorizationState.Principals</c> is still a
|
|
/// list, so adding it later needs no change on the ACL side.
|
|
/// </para>
|
|
/// <para>
|
|
/// <b>The secret is never stored.</b> <see cref="SecretHash"/> holds a peppered HMAC-SHA256 of the
|
|
/// secret half only; the plaintext is shown once at creation and is unrecoverable afterwards.
|
|
/// </para>
|
|
/// <para>
|
|
/// ⚠️ <b>Revocation requires a deploy.</b> Phase 4 leaves driver-only nodes with no ConfigDb, so
|
|
/// keys reach them inside the deployment artifact exactly as <see cref="NodeAcl"/> rows do.
|
|
/// Setting <see cref="Enabled"/> to false takes effect on a node only once a new artifact reaches
|
|
/// it. This is an operational sharp edge, not an oversight.
|
|
/// </para>
|
|
/// </remarks>
|
|
public sealed class ApiKey
|
|
{
|
|
/// <summary>Gets or sets the database row ID for this key.</summary>
|
|
public Guid ApiKeyRowId { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the public key id — the middle segment of <c>otua_<keyId>_<secret></c>.
|
|
/// Carried in the clear so verification is an index seek rather than a scan over every stored hash.
|
|
/// </summary>
|
|
public required string ApiKeyId { get; set; }
|
|
|
|
/// <summary>Gets or sets the human-readable label, e.g. the consuming system's name.</summary>
|
|
public required string Name { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the base64 peppered HMAC-SHA256 of the key's secret segment. Never the secret.
|
|
/// </summary>
|
|
public required string SecretHash { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gets or sets the principal this key authenticates as. <see cref="NodeAcl.Principal"/> rows
|
|
/// naming this value grant it permissions.
|
|
/// </summary>
|
|
public required string Principal { get; set; }
|
|
|
|
/// <summary>Gets or sets whether the key may authenticate. See the revocation caveat on the type.</summary>
|
|
public bool Enabled { get; set; } = true;
|
|
|
|
/// <summary>Gets or sets when the key was created (UTC).</summary>
|
|
public DateTime CreatedUtc { get; set; }
|
|
|
|
/// <summary>Gets or sets when the key expires (UTC); null never expires.</summary>
|
|
public DateTime? ExpiresUtc { get; set; }
|
|
|
|
/// <summary>Gets or sets optional operator notes.</summary>
|
|
public string? Notes { get; set; }
|
|
|
|
/// <summary>Optimistic concurrency token, matching the rest of the live-edit config model.</summary>
|
|
public byte[] RowVersion { get; set; } = Array.Empty<byte>();
|
|
}
|