diff --git a/common/client_types.proto b/common/client_types.proto index 5cc3b38..e713259 100644 --- a/common/client_types.proto +++ b/common/client_types.proto @@ -1,6 +1,8 @@ syntax = "proto3"; package defguard.client_types; +import "enterprise/v2/posture/posture.proto"; + /* * Shared message and enum definitions used by Defguard desktop clients (desktop app and CLI). * @@ -120,6 +122,8 @@ message DeviceConfig { int32 keepalive_interval = 10; optional LocationMfaMode location_mfa_mode = 11; optional ServiceLocationMode service_location_mode = 12; + // added for 2.1 + optional bool posture_check_required = 13; } enum ClientTrafficPolicy { @@ -185,6 +189,8 @@ message ClientMfaStartRequest { int64 location_id = 1; string pubkey = 2; MfaMethod method = 3; + // [2.1] Required when the location has posture policies assigned. + optional defguard.enterprise.posture.v2.DevicePostureData posture_data = 4; } message ClientMfaStartResponse { @@ -232,8 +238,7 @@ message CodeMfaSetupFinishResponse { repeated string recovery_codes = 1; } -// OIDC authentication flow - +// External OIDC authentication flow enum AuthFlowType { AUTH_FLOW_TYPE_UNSPECIFIED = 0; AUTH_FLOW_TYPE_ENROLLMENT = 1; diff --git a/enterprise/v2/posture/posture.proto b/enterprise/v2/posture/posture.proto new file mode 100644 index 0000000..739449b --- /dev/null +++ b/enterprise/v2/posture/posture.proto @@ -0,0 +1,60 @@ +syntax = "proto3"; +package defguard.enterprise.posture.v2; + +enum UnavailableReason { + UNAVAILABLE_REASON_UNSPECIFIED = 0; + UNAVAILABLE_REASON_INSUFFICIENT_PERMISSIONS = 1; + UNAVAILABLE_REASON_NOT_APPLICABLE = 2; + UNAVAILABLE_REASON_DETECTION_FAILED = 3; +} + +// Wrapper for a boolean posture signal that may be unavailable. +message BoolCheck { + oneof result { + bool value = 1; + UnavailableReason unavailable = 2; + } +} + +// Wrapper for a string posture signal that may be unavailable. +message StringCheck { + oneof result { + string value = 1; + UnavailableReason unavailable = 2; + } +} + +// Raw posture signals gathered by the client. +message DevicePostureData { + // Full semver string including any pre-release suffix, e.g. "1.6.0-beta1". + string defguard_client_version = 1; + // Normalized OS type, e.g. "Windows", "macOS", "Linux", "iOS", "Android". + string os_type = 2; + // Detailed OS name, e.g. "Windows", "Darwin", "Ubuntu". + StringCheck os_name = 3; + // OS version string, e.g. "11", "14.5", "22.04". + StringCheck os_version = 4; + BoolCheck disk_encryption = 5; + BoolCheck antivirus_present = 6; + // Windows only + BoolCheck windows_ad_domain_joined = 8; + BoolCheck windows_security_update_current = 9; + // Linux only + StringCheck linux_kernel_version = 10; + // Android and macOS only + BoolCheck device_integrity = 11; +} + +message DevicePostureCheckRequest { + int64 location_id = 1; + string pubkey = 2; + DevicePostureData device_posture_data = 3; +} + +message DevicePostureCheckResponse { + string preshared_key = 1; +} + +message DevicePostureRejection { + repeated string failed_posture_checks = 1; +} diff --git a/v2/proxy.proto b/v2/proxy.proto index ba4bf51..a70f344 100644 --- a/v2/proxy.proto +++ b/v2/proxy.proto @@ -2,6 +2,7 @@ syntax = "proto3"; package defguard.proxy.v2; import "common/client_types.proto"; +import "enterprise/v2/posture/posture.proto"; import "google/protobuf/empty.proto"; import "v2/common.proto"; @@ -109,6 +110,8 @@ message CoreResponse { AwaitRemoteMfaFinishResponse await_remote_mfa_finish = 16; HttpsCerts https_certs = 17; google.protobuf.Empty clear_https_certs = 18; + defguard.enterprise.posture.v2.DevicePostureCheckResponse device_posture_check = 19; + defguard.enterprise.posture.v2.DevicePostureRejection device_posture_rejected = 20; } } @@ -199,6 +202,7 @@ message CoreRequest { defguard.client_types.CodeMfaSetupFinishRequest code_mfa_setup_finish = 19; AwaitRemoteMfaFinishRequest await_remote_mfa_finish = 20; AcmeCertificate acme_certificate = 21; + defguard.enterprise.posture.v2.DevicePostureCheckRequest device_posture_check = 22; } }