From b4646f242060121eb05c668d7657193eb4e4274d Mon Sep 17 00:00:00 2001 From: aman Date: Tue, 2 Sep 2025 17:03:17 +0530 Subject: [PATCH 1/5] feat: Add audit record APIs and deprecate existing audit log APIs --- raystack/frontier/v1beta1/admin.proto | 15 ++++++++ raystack/frontier/v1beta1/frontier.proto | 46 ++++++++++++++++++++++-- raystack/frontier/v1beta1/models.proto | 38 ++++++++++++++++++++ 3 files changed, 96 insertions(+), 3 deletions(-) diff --git a/raystack/frontier/v1beta1/admin.proto b/raystack/frontier/v1beta1/admin.proto index 04d94500..6a479bf9 100644 --- a/raystack/frontier/v1beta1/admin.proto +++ b/raystack/frontier/v1beta1/admin.proto @@ -788,6 +788,9 @@ service AdminService { // Revoke a specific session for a specific user (admin only). rpc RevokeUserSession(RevokeUserSessionRequest) returns (RevokeUserSessionResponse) {} + // Audit Records (Admin Only) + rpc ListAuditRecords(ListAuditRecordsRequest) returns (ListAuditRecordsResponse) {} + } message ListAllUsersRequest { @@ -1720,3 +1723,15 @@ message RevokeUserSessionRequest { } message RevokeUserSessionResponse {} + +// Admin Audit Record messages + +message ListAuditRecordsRequest { + RQLRequest query = 1; +} + +message ListAuditRecordsResponse { + repeated AuditRecord audit_records = 1; + RQLQueryPaginationResponse pagination = 2; + RQLQueryGroupResponse group = 3; +} diff --git a/raystack/frontier/v1beta1/frontier.proto b/raystack/frontier/v1beta1/frontier.proto index 3a049e80..65b24624 100644 --- a/raystack/frontier/v1beta1/frontier.proto +++ b/raystack/frontier/v1beta1/frontier.proto @@ -1308,15 +1308,18 @@ service FrontierService { // Audit logs rpc ListOrganizationAuditLogs(ListOrganizationAuditLogsRequest) returns (ListOrganizationAuditLogsResponse) { + option deprecated = true; option (google.api.http) = {get: "/v1beta1/organizations/{org_id}/auditlogs"}; option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { tags: "AuditLog"; summary: "List audit logs"; - description: "Returns a list of audit logs of an organization in Frontier."; + description: "Returns a list of audit logs of an organization in Frontier. DEPRECATED: Use admin ListAuditRecords API instead."; + deprecated: true; }; } rpc CreateOrganizationAuditLogs(CreateOrganizationAuditLogsRequest) returns (CreateOrganizationAuditLogsResponse) { + option deprecated = true; option (google.api.http) = { post: "/v1beta1/organizations/{org_id}/auditlogs", body: "*" @@ -1324,16 +1327,19 @@ service FrontierService { option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { tags: "AuditLog"; summary: "Create audit log"; - description: "Create new audit logs in a batch."; + description: "Create new audit logs in a batch. DEPRECATED: Use CreateAuditRecord API instead."; + deprecated: true; }; } rpc GetOrganizationAuditLog(GetOrganizationAuditLogRequest) returns (GetOrganizationAuditLogResponse) { + option deprecated = true; option (google.api.http) = {get: "/v1beta1/organizations/{org_id}/auditlogs/{id}"}; option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { tags: "AuditLog"; summary: "Get audit log"; - description: "Get an audit log by ID."; + description: "Get an audit log by ID. DEPRECATED: Use admin GetAuditRecord API instead."; + deprecated: true; }; } @@ -1915,6 +1921,9 @@ service FrontierService { description: "Create prospect for given email and activity. Available for public access."; }; } + + // Audit Records + rpc CreateAuditRecord(CreateAuditRecordRequest) returns (CreateAuditRecordResponse) {} } // Billing @@ -4165,3 +4174,34 @@ message RevokeSessionResponse {} message PingUserSessionRequest {} message PingUserSessionResponse {} + +// Audit Record messages for user-facing API +message CreateAuditRecordRequest { + AuditRecordActor actor = 1 [(google.api.field_behavior) = REQUIRED]; + + string event = 2 [ + (google.api.field_behavior) = REQUIRED, + (validate.rules).string = {min_len: 3} + ]; + + // Base resource on which this change happened + AuditRecordResource resource = 3 [(google.api.field_behavior) = REQUIRED]; + + // Related resource info (optional) + AuditRecordTarget target = 4; + + // When the event occurred + google.protobuf.Timestamp occurred_at = 5 [(google.api.field_behavior) = REQUIRED]; + + string org_id = 6 [(validate.rules).string.uuid = true]; + + // Request ID for tracing + string req_id = 7; + + // Flexible metadata field for any additional data including reason, changes, etc. + google.protobuf.Struct metadata = 8; +} + +message CreateAuditRecordResponse { + AuditRecord audit_record = 1; +} diff --git a/raystack/frontier/v1beta1/models.proto b/raystack/frontier/v1beta1/models.proto index 779dd212..cc169575 100644 --- a/raystack/frontier/v1beta1/models.proto +++ b/raystack/frontier/v1beta1/models.proto @@ -1044,3 +1044,41 @@ message Session { google.protobuf.Timestamp created_at = 4; google.protobuf.Timestamp updated_at = 5; } + +// Audit Record models + +message AuditRecordActor { + string id = 1 [(google.api.field_behavior) = REQUIRED]; + string type = 2 [(google.api.field_behavior) = REQUIRED]; + string name = 3; + google.protobuf.Struct metadata = 4; +} + +message AuditRecordResource { + string id = 1 [(google.api.field_behavior) = REQUIRED]; + string type = 2 [(google.api.field_behavior) = REQUIRED]; + string name = 3; + google.protobuf.Struct metadata = 4; +} + +message AuditRecordTarget { + string id = 1; + string type = 2; + string name = 3; + google.protobuf.Struct metadata = 4; +} + +message AuditRecord { + string id = 1; + + AuditRecordActor actor = 2; + string event = 3; + AuditRecordResource resource = 4; + AuditRecordTarget target = 5; + google.protobuf.Timestamp occurred_at = 6; + string org_id = 7; + string req_id = 8; + google.protobuf.Struct metadata = 9; + + google.protobuf.Timestamp created_at = 10; +} From 2a7d33a6554916b270836ef7b14158be02e6468b Mon Sep 17 00:00:00 2001 From: aman Date: Wed, 3 Sep 2025 11:10:04 +0530 Subject: [PATCH 2/5] chore: Update deprecation notice --- raystack/frontier/v1beta1/frontier.proto | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/raystack/frontier/v1beta1/frontier.proto b/raystack/frontier/v1beta1/frontier.proto index 65b24624..d3eee3e5 100644 --- a/raystack/frontier/v1beta1/frontier.proto +++ b/raystack/frontier/v1beta1/frontier.proto @@ -1327,7 +1327,7 @@ service FrontierService { option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation) = { tags: "AuditLog"; summary: "Create audit log"; - description: "Create new audit logs in a batch. DEPRECATED: Use CreateAuditRecord API instead."; + description: "Create new audit logs in a batch. DEPRECATED: Use ListAuditRecords API instead with filters."; deprecated: true; }; } From 3342b9f6e3c0d74aada1f698d98c655a45fbef82 Mon Sep 17 00:00:00 2001 From: aman Date: Wed, 3 Sep 2025 13:42:52 +0530 Subject: [PATCH 3/5] add uuid validation for actor id --- raystack/frontier/v1beta1/models.proto | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/raystack/frontier/v1beta1/models.proto b/raystack/frontier/v1beta1/models.proto index cc169575..e60011dd 100644 --- a/raystack/frontier/v1beta1/models.proto +++ b/raystack/frontier/v1beta1/models.proto @@ -1048,7 +1048,7 @@ message Session { // Audit Record models message AuditRecordActor { - string id = 1 [(google.api.field_behavior) = REQUIRED]; + string id = 1 [(google.api.field_behavior) = REQUIRED, (validate.rules).string.uuid = true]; string type = 2 [(google.api.field_behavior) = REQUIRED]; string name = 3; google.protobuf.Struct metadata = 4; From edd685bc1aa49c363738bed1e8849f0d0d58c629 Mon Sep 17 00:00:00 2001 From: aman Date: Thu, 4 Sep 2025 14:36:32 +0530 Subject: [PATCH 4/5] make `type` field optional in `AuditRecordActor` --- raystack/frontier/v1beta1/frontier.proto | 1 - raystack/frontier/v1beta1/models.proto | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/raystack/frontier/v1beta1/frontier.proto b/raystack/frontier/v1beta1/frontier.proto index d3eee3e5..7e6d21b1 100644 --- a/raystack/frontier/v1beta1/frontier.proto +++ b/raystack/frontier/v1beta1/frontier.proto @@ -4175,7 +4175,6 @@ message PingUserSessionRequest {} message PingUserSessionResponse {} -// Audit Record messages for user-facing API message CreateAuditRecordRequest { AuditRecordActor actor = 1 [(google.api.field_behavior) = REQUIRED]; diff --git a/raystack/frontier/v1beta1/models.proto b/raystack/frontier/v1beta1/models.proto index e60011dd..7c725667 100644 --- a/raystack/frontier/v1beta1/models.proto +++ b/raystack/frontier/v1beta1/models.proto @@ -1049,7 +1049,7 @@ message Session { message AuditRecordActor { string id = 1 [(google.api.field_behavior) = REQUIRED, (validate.rules).string.uuid = true]; - string type = 2 [(google.api.field_behavior) = REQUIRED]; + string type = 2; // not mandatory if id is zeroUUID string name = 3; google.protobuf.Struct metadata = 4; } From f18997333f7eeacdbec50fd151ff6df5770503e9 Mon Sep 17 00:00:00 2001 From: aman Date: Fri, 5 Sep 2025 11:20:34 +0530 Subject: [PATCH 5/5] add idempotency_key field with UUID validation to AuditRecord --- raystack/frontier/v1beta1/frontier.proto | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/raystack/frontier/v1beta1/frontier.proto b/raystack/frontier/v1beta1/frontier.proto index 7e6d21b1..cdec3b8e 100644 --- a/raystack/frontier/v1beta1/frontier.proto +++ b/raystack/frontier/v1beta1/frontier.proto @@ -4199,6 +4199,11 @@ message CreateAuditRecordRequest { // Flexible metadata field for any additional data including reason, changes, etc. google.protobuf.Struct metadata = 8; + + // Idempotency key to prevent duplicate audit records. Can be used for storing external id. + string idempotency_key = 9 [ + (google.api.field_behavior) = REQUIRED, + (validate.rules).string.uuid = true]; } message CreateAuditRecordResponse {