Source

  1. acme
  2. user
  3. v1

user.proto

proto3 · package acme.user.v1

1syntax = "proto3";
2
3// User accounts and profile data for the Acme identity platform.
4//
5// ## In this package
6//
7// | Type | Purpose |
8// | --- | --- |
9// | [User](../../messages/acme.user.v1.User/) | Identity, lifecycle, and profile data. |
10// | [Address](../../messages/acme.user.v1.Address/) | Postal and billing details. |
11// | [UserState](../../enums/acme.user.v1.UserState/) | Account lifecycle values. |
12// | [UserService](../../services/acme.user.v1.UserService/) | Read, list, create, and watch accounts. |
13//
14// ## Getting started
15//
16// 1. Read the User page for a JSON example and field validation rules.
17// 2. Follow UserService to inspect request types and HTTP bindings.
18// 3. Explore [v2 sessions](../acme.user.v2/) to see this account schema reused.
19//
20// > **Shared types:** the session API imports the v1 User definition rather
21// > than duplicating account fields in another version.
22package acme.user.v1;
24import "acme/security/options.proto";
25import "buf/validate/validate.proto";
26import "google/api/field_behavior.proto";
27import "google/protobuf/timestamp.proto";
29option go_package = "acme.example/user/v1;userv1";
30option java_package = "com.acme.user.v1";
31option (acme.security.owner) = "identity-platform";
33// Lifecycle state of a user account.
34//
35// ## State guide
36//
37// | Value | Meaning |
38// | --- | --- |
39// | `USER_STATE_UNSPECIFIED` | No lifecycle state has been supplied. |
40// | `USER_STATE_ACTIVE` | The account is active. |
41// | `USER_STATE_SUSPENDED` | The account is suspended. |
42// | `USER_STATE_DELETED` | Deprecated; retained for compatibility. |
43enum UserState {
44 USER_STATE_UNSPECIFIED = 0;
45 USER_STATE_ACTIVE = 1;
46 USER_STATE_SUSPENDED = 2;
47 USER_STATE_DELETED = 3 [deprecated = true];
50// Postal or billing address nested on a user.
51message Address {
52 string line1 = 1 [(buf.validate.field).string.min_len = 1];
53 string line2 = 2;
54 string city = 3;
55 string region = 4;
56 string postal_code = 5;
57 string country_code = 6 [(buf.validate.field).string = { min_len: 2, max_len: 2 }];
60// A user account in the Acme identity platform.
61//
62// Users are the primary subject of authentication, billing, and support
63// workflows. Changing the shape of this message is a PACKAGE-breaking change.
64//
65// ## Reading a user
66//
67// - **Identity:** `id` is a stable UUID; `email` is the required login address.
68// - **Lifecycle:** `state`, `created_at`, and `updated_at` describe the account.
69// - **Profile:** `display_name`, `nickname`, and `preferences` hold presentation
70// choices. Postal details use the [Address message](../acme.user.v1.Address/).
71//
72// ## Example JSON
73//
74// This response uses the [ProtoJSON mapping](https://protobuf.dev/programming-guides/json/):
75// field names become lower camel case and enum values remain strings.
76//
77// ```json
78// {
79// "id": "550e8400-e29b-41d4-a716-446655440000",
80// "email": "alex@example.com",
81// "displayName": "Alex Chen",
82// "state": "USER_STATE_ACTIVE",
83// "createdAt": "2026-01-15T09:30:00Z",
84// "preferences": {
85// "marketingOptIn": false,
86// "locale": "en-GB",
87// "timeZone": "Europe/London"
88// }
89// }
90// ```
91//
92// ## Creating an account
93//
94// 1. Set the required `email` and choose a `display_name` of 1 to 80 characters.
95// 2. Add profile preferences or up to five postal addresses as needed.
96// 3. Omit the output-only `id`, `created_at`, and `updated_at` fields from input.
97//
98// > **Privacy:** email and phone fields carry PII annotations. Their masking
99// > and hashing policies describe how consumers should handle sensitive data;
100// > the schema itself does not redact values.
101message User {
102 option (acme.security.audit_required) = true;
104 reserved 3, 15 to 20;
105 reserved "legacy_id";
107 // Stable identifier. Never reused.
108 string id = 1 [
109 (google.api.field_behavior) = IDENTIFIER,
110 (google.api.field_behavior) = OUTPUT_ONLY,
111 (buf.validate.field).string.uuid = true
112 ];
114 // Login email. **PII:** follow the `identity/email` masking policy.
115 string email = 2 [
116 (google.api.field_behavior) = REQUIRED,
117 (acme.security.pii) = {
118 sensitive: true
119 redaction: REDACTION_MASK
120 policy: "identity/email"
121 },
122 (buf.validate.field).string.email = true
123 ];
125 string display_name = 4 [
126 (buf.validate.field).string = { min_len: 1, max_len: 80 }
127 ];
129 optional string nickname = 5;
131 UserState state = 6;
133 google.protobuf.Timestamp created_at = 7 [
134 (google.api.field_behavior) = OUTPUT_ONLY
135 ];
137 google.protobuf.Timestamp updated_at = 8 [
138 (google.api.field_behavior) = OUTPUT_ONLY
139 ];
141 // An optional contact channel in addition to the login email.
142 //
143 // - `phone` carries the `identity/phone` hashing policy.
144 // - `pager` is **deprecated** and remains only for compatibility.
145 //
146 // A `oneof` can contain at most one of these values at a time.
147 oneof contact {
148 string phone = 9 [
149 (acme.security.pii) = {
150 sensitive: true
151 redaction: REDACTION_HASH
152 policy: "identity/phone"
153 }
154 ];
155 string pager = 10 [deprecated = true];
156 }
158 map<string, string> labels = 11;
160 repeated Address addresses = 12 [(buf.validate.field).repeated.max_items = 5];
162 // Nested profile preferences.
163 //
164 // ### Example choices
165 //
166 // | Field | Example | Purpose |
167 // | --- | --- | --- |
168 // | `marketing_opt_in` | `false` | Marketing preference. |
169 // | `locale` | `en-GB` | Language and regional formatting. |
170 // | `time_zone` | `Europe/London` | Local time presentation. |
171 //
172 // These strings have no validation rules in this example schema.
173 message Preferences {
174 bool marketing_opt_in = 1;
175 string locale = 2;
176 string time_zone = 3;
177 }
179 Preferences preferences = 13;
182message GetUserRequest {
183 string id = 1 [
184 (google.api.field_behavior) = REQUIRED,
185 (buf.validate.field).string.uuid = true
186 ];
189message GetUserResponse {
190 User user = 1;
193message ListUsersRequest {
194 int32 page_size = 1 [(buf.validate.field).int32 = { gte: 0, lte: 100 }];
195 string page_token = 2;
196 string filter = 3;
199message ListUsersResponse {
200 repeated User users = 1;
201 string next_page_token = 2;
204message CreateUserRequest {
205 User user = 1 [(google.api.field_behavior) = REQUIRED];
208message CreateUserResponse {
209 User user = 1;