Join codes need no passkey touch and carry only public values (genesis fingerprint, owner credentials, installer hashes). Nodes pin the genesis and owners at enrollment and only follow passkey-signed operator set versions. The panel's server key is listed in the set; pinned nodes require its signature and run the control link under AES-256-GCM. Password sessions carry no capabilities. The updater adopts a next_key from a signed manifest. Bump version to 0.2.0. [CI SKIP]
82 lines
2.6 KiB
C#
82 lines
2.6 KiB
C#
using System.Text.Json;
|
||
using System.Text.Json.Serialization;
|
||
|
||
namespace Fleet.Server;
|
||
|
||
public sealed class EnrollRequest
|
||
{
|
||
[JsonPropertyName("join_token")]
|
||
public string JoinToken { get; set; } = "";
|
||
|
||
[JsonPropertyName("name")]
|
||
public string Name { get; set; } = "";
|
||
|
||
/// <summary>身份公钥(SPKI,base64)。</summary>
|
||
[JsonPropertyName("pubkey")]
|
||
public string PublicKey { get; set; } = "";
|
||
|
||
/// <summary>面向对端节点的 TLS 证书指纹(SHA-256,base64)。</summary>
|
||
[JsonPropertyName("tls_spki")]
|
||
public string TlsSpki { get; set; } = "";
|
||
|
||
/// <summary>
|
||
/// 同一把 TLS 密钥的完整公钥(SPKI,base64),必须和 <see cref="TlsSpki"/> 对得上。节点用这把密钥做对等面的签名认证
|
||
/// (和连服务端用的身份密钥是两把独立的密钥),对端要验签就需要完整的公钥,而不只是指纹。
|
||
/// </summary>
|
||
[JsonPropertyName("tls_pubkey")]
|
||
public string TlsPublicKey { get; set; } = "";
|
||
|
||
/// <summary>持有证明:对 <c>fleet|v1|enroll|{sha256_hex(join_token)}|{pubkey}</c> 的签名(base64)。</summary>
|
||
[JsonPropertyName("proof")]
|
||
public string Proof { get; set; } = "";
|
||
|
||
[JsonPropertyName("node_version")]
|
||
public string NodeVersion { get; set; } = "";
|
||
|
||
[JsonPropertyName("meta")]
|
||
public JsonElement? Meta { get; set; }
|
||
}
|
||
|
||
public sealed class TrustRequest
|
||
{
|
||
[JsonPropertyName("join_token")]
|
||
public string JoinToken { get; set; } = "";
|
||
}
|
||
|
||
public sealed class EnrollResponse
|
||
{
|
||
[JsonPropertyName("node_id")]
|
||
public string NodeId { get; set; } = "";
|
||
|
||
/// <summary>pending | active</summary>
|
||
[JsonPropertyName("status")]
|
||
public string Status { get; set; } = "";
|
||
}
|
||
|
||
/// <summary>RFC 9457 problem+json,带 <c>code</c> 扩展字段。</summary>
|
||
public sealed class FleetProblem
|
||
{
|
||
[JsonPropertyName("type")]
|
||
public string Type { get; set; } = "about:blank";
|
||
|
||
[JsonPropertyName("title")]
|
||
public string Title { get; set; } = "";
|
||
|
||
[JsonPropertyName("status")]
|
||
public int Status { get; set; }
|
||
|
||
[JsonPropertyName("code")]
|
||
public string Code { get; set; } = "";
|
||
|
||
[JsonPropertyName("detail")]
|
||
public string? Detail { get; set; }
|
||
}
|
||
|
||
[JsonSourceGenerationOptions(DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)]
|
||
[JsonSerializable(typeof(EnrollRequest))]
|
||
[JsonSerializable(typeof(EnrollResponse))]
|
||
[JsonSerializable(typeof(TrustRequest))]
|
||
[JsonSerializable(typeof(Fleet.Core.TrustBundle))]
|
||
[JsonSerializable(typeof(FleetProblem))]
|
||
internal sealed partial class EnrollmentJsonContext : JsonSerializerContext;
|