Add generation-bound TLS control face

Create ephemeral trust anchors, publish an exact-profile Unix control socket, and persist generation-authorized mTLS session registration through the Domain Store.
This commit is contained in:
ms2k 2026-07-15 17:54:46 +09:00
commit c3a76ec8c4
3 changed files with 2351 additions and 17 deletions

View file

@ -197,6 +197,44 @@ pub struct ProtocolPublicationIdentity {
pub coordinator_tls_certificate_sha256: CertificateDigest,
}
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
pub struct ClientEnrollmentRequest {
pub protocol_version: ProtocolVersion,
pub generation_identity: GenerationIdentity,
pub cli_id: ClientId,
pub certificate_signing_request_der: Vec<u8>,
}
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
pub struct ClientEnrollmentResponse {
pub protocol_version: ProtocolVersion,
pub credential: TlsCredential,
}
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
pub struct SessionRegistrationRequest {
pub protocol_version: ProtocolVersion,
pub session_binding: SessionBinding,
}
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
pub struct SessionRegistrationResponse {
pub protocol_version: ProtocolVersion,
pub session_capability: SessionRequestCapability,
}
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
pub enum ControlRequest {
Enroll(ClientEnrollmentRequest),
Register(SessionRegistrationRequest),
}
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
pub enum ControlResponse {
Enrolled(ClientEnrollmentResponse),
Registered(SessionRegistrationResponse),
}
#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
pub enum ProtocolCredentialRole {
SessionCoordinator,

View file

@ -1,20 +1,21 @@
use super::{
AddressFamily, AddressFamilyDisposition, ArtifactLease, ArtifactState,
ConfigurationFingerprintRecordV1, DefaultAction, DeniedDestinationObservation,
DerivedNetworkPolicy, DeveloperDecision, DeveloperDecisionKind, DnsObservation, Domain,
DomainStore, EnvironmentReference, EscalationOutcome, Generation, GenerationIdentity,
GitRoutingOwnership, GuestProcessIdentity, HelperOwnership, HostProcessIdentity,
HostProcessOwnershipSlot, Mailbox, MailboxCancellation, MailboxRequest, MailboxResult,
MailboxResultAck, MailboxResultChunk, MountIdentity, NamespaceIdentity, NetworkObservation,
NetworkOwnership, NetworkReachabilityProbe, NetworkReadinessAttestation,
NetworkReadinessEvidence, NetworkReadinessIdentity, Participant, ParticipantOwnership,
ParticipantState, PermittedDestinationObservation, PersistedHostProcessOwnership,
PidfsProcessAuthorityV1, PidfsProcessIdentityV1, PolicyAction, PolicyDelivery, PrefixRule,
PrepareOperation, PrepareStageState, PreparedArtifact, PreparedLowerOwnership,
ProcessOwnershipCommitAck, ProcessOwnershipMessageVersion, ProtocolCredential,
ProtocolCredentialRole, ProtocolPublicationIdentity, PtyIdentity, PublicationOwnership,
ResolvedAutoApprovalRule, ResolvedVolume, Resolver, ResultStream, SandboxCredentialBundle,
SandboxOwnership, Session, SessionBinding, SessionClose, SessionExit, SessionExitOutcome,
AddressFamily, AddressFamilyDisposition, ArtifactLease, ArtifactState, ClientEnrollmentRequest,
ClientEnrollmentResponse, ConfigurationFingerprintRecordV1, ControlRequest, ControlResponse,
DefaultAction, DeniedDestinationObservation, DerivedNetworkPolicy, DeveloperDecision,
DeveloperDecisionKind, DnsObservation, Domain, DomainStore, EnvironmentReference,
EscalationOutcome, Generation, GenerationIdentity, GitRoutingOwnership, GuestProcessIdentity,
HelperOwnership, HostProcessIdentity, HostProcessOwnershipSlot, Mailbox, MailboxCancellation,
MailboxRequest, MailboxResult, MailboxResultAck, MailboxResultChunk, MountIdentity,
NamespaceIdentity, NetworkObservation, NetworkOwnership, NetworkReachabilityProbe,
NetworkReadinessAttestation, NetworkReadinessEvidence, NetworkReadinessIdentity, Participant,
ParticipantOwnership, ParticipantState, PermittedDestinationObservation,
PersistedHostProcessOwnership, PidfsProcessAuthorityV1, PidfsProcessIdentityV1, PolicyAction,
PolicyDelivery, PrefixRule, PrepareOperation, PrepareStageState, PreparedArtifact,
PreparedLowerOwnership, ProcessOwnershipCommitAck, ProcessOwnershipMessageVersion,
ProtocolCredential, ProtocolCredentialRole, ProtocolPublicationIdentity, PtyIdentity,
PublicationOwnership, ResolvedAutoApprovalRule, ResolvedVolume, Resolver, ResultStream,
SandboxCredentialBundle, SandboxOwnership, Session, SessionBinding, SessionClose, SessionExit,
SessionExitOutcome, SessionRegistrationRequest, SessionRegistrationResponse,
SessionRequestCapability, SessionTerminal, SessionTerminalEvent, SessionTerminalMessage,
SessionTerminalState, SignedProtocolRecord, StagedProcessOwnership, StateAnchorOwnership,
StorageCatalog, StoreMetadata, TerminalInput, TerminalOutput, TerminalResize, TerminalSignal,
@ -76,6 +77,12 @@ schema_types!(
"TrustManifest" => TrustManifest,
"TlsCredential" => TlsCredential,
"ProtocolPublicationIdentity" => ProtocolPublicationIdentity,
"ClientEnrollmentRequest" => ClientEnrollmentRequest,
"ClientEnrollmentResponse" => ClientEnrollmentResponse,
"SessionRegistrationRequest" => SessionRegistrationRequest,
"SessionRegistrationResponse" => SessionRegistrationResponse,
"ControlRequest" => ControlRequest,
"ControlResponse" => ControlResponse,
"SandboxCredentialBundle" => SandboxCredentialBundle,
"TlsRole" => TlsRole,
"ProtocolCredential" => ProtocolCredential,

View file

@ -190,6 +190,30 @@ fn every_schema_shape_round_trips_and_rejects_malformed_or_unknown_versions() {
},
&mut seen,
);
let enrollment_request = ClientEnrollmentRequest {
protocol_version: ProtocolVersion::V1,
generation_identity: generation_identity(),
cli_id: ClientId::new(opaque(13)),
certificate_signing_request_der: vec![56],
};
let enrollment_response = ClientEnrollmentResponse {
protocol_version: ProtocolVersion::V1,
credential: tls_credential.clone(),
};
let registration_request = SessionRegistrationRequest {
protocol_version: ProtocolVersion::V1,
session_binding: session_binding(),
};
let registration_response = SessionRegistrationResponse {
protocol_version: ProtocolVersion::V1,
session_capability: session_capability(),
};
verify_shape(enrollment_request.clone(), &mut seen);
verify_shape(enrollment_response.clone(), &mut seen);
verify_shape(registration_request.clone(), &mut seen);
verify_shape(registration_response.clone(), &mut seen);
verify_shape(ControlRequest::Enroll(enrollment_request), &mut seen);
verify_shape(ControlResponse::Enrolled(enrollment_response), &mut seen);
verify_shape(
SandboxCredentialBundle::new(
generation_identity(),
@ -841,3 +865,30 @@ fn unknown_enums_and_protocol_versions_are_rejected() {
Err(CodecError::MalformedPayload(_))
));
}
#[test]
fn control_wire_unknown_protocol_versions_are_rejected() {
assert_unknown_protocol_version(&ClientEnrollmentRequest {
protocol_version: ProtocolVersion::V1,
generation_identity: generation_identity(),
cli_id: ClientId::new(opaque(4)),
certificate_signing_request_der: vec![5],
});
assert_unknown_protocol_version(&ClientEnrollmentResponse {
protocol_version: ProtocolVersion::V1,
credential: TlsCredential::client_cli(
generation_identity(),
ClientId::new(opaque(4)),
vec![5],
CertificateDigest::new(opaque(6)),
),
});
assert_unknown_protocol_version(&SessionRegistrationRequest {
protocol_version: ProtocolVersion::V1,
session_binding: session_binding(),
});
assert_unknown_protocol_version(&SessionRegistrationResponse {
protocol_version: ProtocolVersion::V1,
session_capability: session_capability(),
});
}