Skip to content

Commit 7adfe3b

Browse files
authored
setup protobuf versioning (#71)
* snapshot current main branch as v1 * adjust module naming * restore top-level enterprise directory * snapshot dev branch as v2 * add missing firewall module * update imports * add buf CLI setup * formatting * add buf CLI section to readme * remove unnecessary file * add CI workflow * skip job * remove legacy services from v2 protos * extract client types into a shared module * adjust v2 structure * formatting * fix missing types * remove deprecated fields * restore AuthInfoRequest and migrate it to client types * extract remaining client-related types to shared module * update field order * sort messages * put cert-related messages in a shared package * update shared client types and use them in v1 * post-merge fix * use timestamp for wireguard handshake * align clean up naming and formatting * formatting
1 parent f600c25 commit 7adfe3b

16 files changed

Lines changed: 991 additions & 594 deletions

File tree

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
name: Proto validation
2+
3+
on:
4+
pull_request:
5+
types:
6+
- opened
7+
- synchronize
8+
- reopened
9+
paths:
10+
- "**/*.proto"
11+
- "buf.yaml"
12+
- ".github/workflows/proto-validate.yml"
13+
14+
permissions:
15+
contents: read
16+
17+
jobs:
18+
validate:
19+
runs-on: ubuntu-latest
20+
21+
steps:
22+
- name: Check out repository
23+
uses: actions/checkout@v6
24+
with:
25+
fetch-depth: 0
26+
27+
- name: Set up Buf
28+
uses: bufbuild/buf-setup-action@v1
29+
30+
- name: Check formatting
31+
run: buf format --diff --exit-code
32+
33+
- name: Build image
34+
run: buf build
35+
36+
- name: Lint protobuf
37+
run: buf lint
38+
39+
- name: Check breaking changes for v1
40+
# Remove once new file structure is actually merged into base branch.
41+
continue-on-error: true
42+
run: |
43+
buf breaking \
44+
--against ".git#ref=${{ github.event.pull_request.base.sha }}" \
45+
--path v1 \
46+
--path enterprise/v1
47+
48+
- name: Check breaking changes for v2
49+
# Remove when v2 compatibility is enforced.
50+
continue-on-error: true
51+
run: |
52+
buf breaking \
53+
--against ".git#ref=${{ github.event.pull_request.base.sha }}" \
54+
--path v2 \
55+
--path enterprise/v2

README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,14 @@
88

99
See the [documentation](https://defguard.gitbook.io) for more information about the system.
1010

11+
## Buf CLI
12+
13+
This repository uses [Buf](https://buf.build/) to validate the protobuf module layout and schema quality across the versioned snapshots in `v1/`, `v2/`, `enterprise/v1/`, and `enterprise/v2/`. Imports are repo-root-relative.
14+
15+
- `buf build` — verify that the module and imports resolve correctly.
16+
- `buf lint` — run the repository's Buf lint rules.
17+
- `buf format -w` — format .proto files.
18+
1119
## Community and Support
1220

1321
Find us on Matrix: [#defguard:teonite.com](https://matrix.to/#/#defguard:teonite.com)

buf.yaml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
version: v2
2+
modules:
3+
- path: .
4+
excludes:
5+
- .direnv
6+
lint:
7+
use:
8+
- BASIC
9+
except:
10+
- DIRECTORY_SAME_PACKAGE
11+
- PACKAGE_DIRECTORY_MATCH
12+
breaking:
13+
use:
14+
- FILE

common/client_types.proto

Lines changed: 248 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,248 @@
1+
syntax = "proto3";
2+
package defguard.client_types;
3+
4+
/*
5+
* Shared message and enum definitions used by Defguard desktop clients (desktop app and CLI).
6+
*
7+
* This module exists to decouple the desktop client from any specific proxy protocol version.
8+
* The client only needs a stable, version-independent set of types for:
9+
* - Enrollment and device configuration (DeviceConfigResponse and its dependencies)
10+
* - Periodic configuration polling (InstanceInfoRequest/Response)
11+
* - Platform info reporting (ClientPlatformInfo)
12+
*
13+
* Both v1 and v2 proxy protocol definitions import this file and reference these types in
14+
* their CoreRequest/CoreResponse envelopes, ensuring that a single client build can
15+
* communicate with proxies running either protocol version without any code changes.
16+
*
17+
* Types that are proxy-version-specific (e.g. gRPC envelope messages, setup/certificate
18+
* provisioning, password reset flows) are intentionally NOT included here.
19+
*/
20+
21+
// Enrollment & Desktop Client activation
22+
23+
message EnrollmentStartRequest {
24+
string token = 1;
25+
}
26+
27+
message AdminInfo {
28+
string name = 1;
29+
optional string phone_number = 2;
30+
string email = 3;
31+
}
32+
33+
message InitialUserInfo {
34+
string first_name = 1;
35+
string last_name = 2;
36+
string login = 3;
37+
string email = 4;
38+
optional string phone_number = 5;
39+
bool is_active = 6;
40+
repeated string device_names = 7;
41+
bool enrolled = 8;
42+
bool is_admin = 9;
43+
}
44+
45+
message EnrollmentSettings {
46+
// Vpn step is skippable
47+
bool vpn_setup_optional = 1;
48+
// Manual WireGuard setup is disabled
49+
bool only_client_activation = 2;
50+
// Only admins can add devices so vpn step is skipped
51+
bool admin_device_management = 3;
52+
// Enable Email method for MFA setup
53+
bool smtp_configured = 4;
54+
// MFA setup is not skippable
55+
bool mfa_required = 5;
56+
}
57+
58+
message EnrollmentStartResponse {
59+
AdminInfo admin = 1;
60+
InitialUserInfo user = 2;
61+
int64 deadline_timestamp = 3;
62+
string final_page_content = 5;
63+
InstanceInfo instance = 7;
64+
EnrollmentSettings settings = 8;
65+
}
66+
67+
message ActivateUserRequest {
68+
optional string phone_number = 1;
69+
string password = 2;
70+
optional string token = 3;
71+
}
72+
73+
message NewDevice {
74+
string name = 1;
75+
string pubkey = 2;
76+
optional string token = 3;
77+
}
78+
79+
message ExistingDevice {
80+
string pubkey = 1;
81+
optional string token = 2;
82+
}
83+
84+
message Device {
85+
int64 id = 1;
86+
string name = 2;
87+
string pubkey = 3;
88+
int64 user_id = 4;
89+
int64 created_at = 5;
90+
}
91+
92+
// Device configuration
93+
94+
enum LocationMfaMode {
95+
LOCATION_MFA_MODE_UNSPECIFIED = 0;
96+
LOCATION_MFA_MODE_DISABLED = 1;
97+
LOCATION_MFA_MODE_INTERNAL = 2;
98+
LOCATION_MFA_MODE_EXTERNAL = 3;
99+
}
100+
101+
enum ServiceLocationMode {
102+
SERVICE_LOCATION_MODE_UNSPECIFIED = 0;
103+
SERVICE_LOCATION_MODE_DISABLED = 1;
104+
SERVICE_LOCATION_MODE_PRELOGON = 2;
105+
SERVICE_LOCATION_MODE_ALWAYSON = 3;
106+
}
107+
108+
message DeviceConfig {
109+
int64 network_id = 1;
110+
string network_name = 2;
111+
string config = 3;
112+
string endpoint = 4;
113+
string assigned_ip = 5;
114+
// network pubkey
115+
string pubkey = 6;
116+
string allowed_ips = 7;
117+
optional string dns = 8;
118+
// DEPRECATED(1.5): superseded by location_mfa_mode
119+
bool mfa_enabled = 9 [deprecated = true];
120+
int32 keepalive_interval = 10;
121+
optional LocationMfaMode location_mfa_mode = 11;
122+
optional ServiceLocationMode service_location_mode = 12;
123+
}
124+
125+
enum ClientTrafficPolicy {
126+
NONE = 0;
127+
DISABLE_ALL_TRAFFIC = 1;
128+
FORCE_ALL_TRAFFIC = 2;
129+
}
130+
131+
message InstanceInfo {
132+
string id = 1;
133+
string name = 2;
134+
string url = 3;
135+
string proxy_url = 4;
136+
string username = 5;
137+
bool enterprise_enabled = 6;
138+
// DEPRECATED(1.6): superseded by client_traffic_policy
139+
bool disable_all_traffic = 7 [deprecated = true];
140+
optional string openid_display_name = 8;
141+
optional ClientTrafficPolicy client_traffic_policy = 9;
142+
}
143+
144+
message DeviceConfigResponse {
145+
Device device = 1;
146+
repeated DeviceConfig configs = 2;
147+
InstanceInfo instance = 3;
148+
// polling token used for further client-core communication
149+
optional string token = 4;
150+
}
151+
152+
// Configuration polling
153+
154+
message InstanceInfoRequest {
155+
string token = 1;
156+
}
157+
158+
message InstanceInfoResponse {
159+
DeviceConfigResponse device_config = 1;
160+
}
161+
162+
// Platform info sent as a header with every request to the proxy
163+
164+
message ClientPlatformInfo {
165+
string os_family = 1;
166+
string os_type = 2;
167+
string version = 3;
168+
optional string edition = 4;
169+
optional string codename = 5;
170+
optional string bitness = 6;
171+
optional string architecture = 7;
172+
}
173+
174+
// Client MFA
175+
176+
enum MfaMethod {
177+
TOTP = 0;
178+
EMAIL = 1;
179+
OIDC = 2;
180+
BIOMETRIC = 3;
181+
MOBILE_APPROVE = 4;
182+
}
183+
184+
message ClientMfaStartRequest {
185+
int64 location_id = 1;
186+
string pubkey = 2;
187+
MfaMethod method = 3;
188+
}
189+
190+
message ClientMfaStartResponse {
191+
string token = 1;
192+
// for biometric mfa method
193+
optional string challenge = 2;
194+
}
195+
196+
message ClientMfaFinishRequest {
197+
string token = 1;
198+
optional string code = 2;
199+
optional string auth_pub_key = 3;
200+
}
201+
202+
message ClientMfaFinishResponse {
203+
string preshared_key = 1;
204+
optional string token = 2;
205+
}
206+
207+
message RegisterMobileAuthRequest {
208+
string token = 1;
209+
string auth_pub_key = 2;
210+
string device_pub_key = 3;
211+
}
212+
213+
// TOTP and Email MFA Setup
214+
215+
message CodeMfaSetupStartRequest {
216+
MfaMethod method = 1;
217+
string token = 2;
218+
}
219+
220+
// in case of email secret is empty
221+
message CodeMfaSetupStartResponse {
222+
optional string totp_secret = 1;
223+
}
224+
225+
message CodeMfaSetupFinishRequest {
226+
string code = 1;
227+
string token = 2;
228+
MfaMethod method = 3;
229+
}
230+
231+
message CodeMfaSetupFinishResponse {
232+
repeated string recovery_codes = 1;
233+
}
234+
235+
// OIDC authentication flow
236+
237+
enum AuthFlowType {
238+
AUTH_FLOW_TYPE_UNSPECIFIED = 0;
239+
AUTH_FLOW_TYPE_ENROLLMENT = 1;
240+
AUTH_FLOW_TYPE_MFA = 2;
241+
}
242+
243+
message AuthInfoRequest {
244+
// DEPRECATED(2.0): superseded by auth_flow_type; kept for legacy client compatibility
245+
string redirect_url = 1 [deprecated = true];
246+
optional string state = 2;
247+
AuthFlowType auth_flow_type = 3;
248+
}

0 commit comments

Comments
 (0)