audit-go/proto/audit/v1/audit_event.proto
Mathias Koehrer (EXT) 84c49f2690 Merged PR 889470: feat: Add more validation to proto schema
Made the initiator.email optional and added a new validation.
Added a new regex pattern to string fields to prevent them from consisting only of whitespace.

Security-concept-update-needed: false

JIRA Work Item: [STACKITRMA-677](https://jira.schwarz/browse/STACKITRMA-677)
2025-11-27 14:52:27 +00:00

619 lines
21 KiB
Protocol Buffer

syntax = "proto3";
package audit.v1;
import "buf/validate/validate.proto";
import "google/protobuf/struct.proto";
import "google/protobuf/timestamp.proto";
import "google/protobuf/wrappers.proto";
option go_package = "./audit;auditV1";
option java_multiple_files = true;
option java_package = "com.schwarz.stackit.audit.v1";
// The audit log entry can be used to record an incident in the audit log.
message AuditLogEntry {
// The resource name of the log to which this log entry belongs.
//
// Format: <pluralType>/<identifier>/logs/<eventType>
// Where:
// Plural-Types: One from the list of supported ObjectType as plural
// Event-Types: admin-activity, system-event, policy-denied, data-access
//
// Examples:
// "projects/00b0f972-59ff-48f2-a4f9-29c57b75c2fa/logs/admin-activity"
// "billing-accounts/00b0f972-59ff-48f2-a4f9-29c57b75c2fa/logs/admin-activity"
//
// Required: true
string log_name = 1 [
(buf.validate.field).required = true,
(buf.validate.field).string.pattern = "^[a-z-]+/[a-z0-9-]+/logs/(?:admin-activity|system-event|policy-denied|data-access)$"
];
// The log entry payload, which is always an AuditLog for STACKIT Audit Log events.
//
// Required: true
AuditLog proto_payload = 2 [(buf.validate.field).required = true];
// A unique identifier for the log entry.
// Is used to check completeness of audit events over time.
//
// Format: <unix-timestamp>/<region-zone>/<worker-id>/<sequence-number>
// Where:
// Unix-Timestamp: A UTC unix timestamp in seconds is expected
// Region-Zone: The region and (optional) zone id. If both, separated with a - (dash)
// Worker-Id: The ID of the K8s Pod, Service-Instance, etc (must be unique for a sending service)
// Sequence-Number: Increasing number, representing the message offset per Worker-Id
// If the Worker-Id changes, the sequence-number has to be reset to 0.
//
// Examples:
// "1721899117/eu01/319a7fb9-edd2-46c6-953a-a724bb377c61/8792726390909855142"
// "1721899117/eu01-m/319a7fb9-edd2-46c6-953a-a724bb377c61/8792726390909855142"
//
// Required: true
string insert_id = 3 [
(buf.validate.field).required = true,
(buf.validate.field).string.pattern = "^[0-9]+/[a-z0-9-]+/[a-z0-9-]+/[0-9]+$"
];
// A set of user-defined (key, value) data that provides additional
// information about the log entry.
//
// Required: false
map<string, string> labels = 4;
// Correlate multiple audit logs by setting the same id
//
// Required: false
optional string correlation_id = 5 [
(buf.validate.field).string.min_len = 1,
(buf.validate.field).string.max_len = 255
];
// The time the event described by the log entry occurred.
//
// Required: true
google.protobuf.Timestamp timestamp = 6 [
(buf.validate.field).required = true,
(buf.validate.field).timestamp.lt_now = true
];
// The severity of the log entry.
//
// Required: true
LogSeverity severity = 7 [
(buf.validate.field).required = true,
(buf.validate.field).enum.defined_only = true
];
}
// The severity of the event described in a log entry, expressed as one of the
// standard severity levels listed below.
enum LogSeverity {
LOG_SEVERITY_UNSPECIFIED = 0;
// The log entry has no assigned severity level.
LOG_SEVERITY_DEFAULT = 100;
// Debug or trace information.
LOG_SEVERITY_DEBUG = 200;
// Routine information, such as ongoing status or performance.
LOG_SEVERITY_INFO = 300;
// Normal but significant events, such as start up, shut down, or
// a configuration change.
LOG_SEVERITY_NOTICE = 400;
// Warning events might cause problems.
LOG_SEVERITY_WARNING = 500;
// Error events are likely to cause problems.
LOG_SEVERITY_ERROR = 600;
// Critical events cause more severe problems or outages.
LOG_SEVERITY_CRITICAL = 700;
// A person must take an action immediately.
LOG_SEVERITY_ALERT = 800;
// One or more systems are unusable.
LOG_SEVERITY_EMERGENCY = 900;
}
// Common audit log format for STACKIT API operations.
message AuditLog {
// The name of the API service performing the operation.
//
// Examples:
// "resource-manager"
//
// Required: true
string service_name = 1 [
(buf.validate.field).required = true,
(buf.validate.field).string.min_len = 1,
(buf.validate.field).string.pattern = ".*\\S.*"
];
// The name of the service method or operation.
//
// Format: stackit.<product>.<version>.<type-chain>.<operation>
// Where:
// Product: The name of the service in lowercase
// Version: Optional API version
// Type-Chain: Chained path to object
// Operation: The name of the operation in lowercase
//
// Examples:
// "stackit.resource-manager.v1.organizations.create"
// "stackit.authorization.v1.projects.volumes.create"
// "stackit.authorization.v2alpha.projects.volumes.create"
// "stackit.authorization.v2.folders.move"
// "stackit.resource-manager.health"
//
// Required: true
string operation_name = 2 [
(buf.validate.field).required = true,
(buf.validate.field).string.pattern = "^stackit\\.[a-z0-9-]+\\.(?:v[0-9]+\\.)?(?:[a-z0-9-.]+\\.)?[a-z0-9-]+$",
(buf.validate.field).string.min_len = 1,
(buf.validate.field).string.max_len = 255
];
// The resource or collection that is the target of the operation.
// The name is a scheme-less URI, not including the API service name.
//
// Format: <pluralType>/<id>[/<details>]
// Where:
// Plural-Type: One from the list of supported ObjectType as plural
// Id: The identifier of the object
// Details: Optional "<key>/<id>" pairs
//
// Examples:
// "organizations/40ab14ad-b7b0-4b1c-be41-5bc820a968d1"
// "projects/7046e7b6-5ae9-441c-99fe-2cd28a5078ec/locations/_/instances/instance-20240723-174217"
// "projects/7046e7b6-5ae9-441c-99fe-2cd28a5078ec/locations/sx-stoi01/instances/instance-20240723-174217"
// "projects/dd7d1807-54e9-4426-8994-721758b5b554/locations/eu01/vms/b6851b4e-7a9d-4973-ab0f-a80a13ee3060/ports/78f8bad4-a291-4fa3-b07f-4a1985d3dbe8"
// "projects/dd7d1807-54e9-4426-8994-721758b5b554/locations/eu01-m/vms/b6851b4e-7a9d-4973-ab0f-a80a13ee3060/ports/78f8bad4-a291-4fa3-b07f-4a1985d3dbe8"
//
// Required: true
string resource_name = 3 [
(buf.validate.field).required = true,
(buf.validate.field).string.pattern = "^[a-z]+/[a-z0-9-]+(?:/[a-z0-9-]+/[a-z0-9-_]+)*$",
(buf.validate.field).string.min_len = 1,
(buf.validate.field).string.max_len = 255
];
// Authentication information.
//
// Required: true
AuthenticationInfo authentication_info = 4 [(buf.validate.field).required = true];
// Authorization information. If there are multiple resources or permissions involved, then there is
// one AuthorizationInfo element for each {resource, permission} tuple.
//
// Required: false
repeated AuthorizationInfo authorization_info = 5;
// Metadata about the operation.
//
// Required: true
RequestMetadata request_metadata = 6 [(buf.validate.field).required = true];
// The operation request. This may not include all request parameters,
// such as those that are too large, privacy-sensitive, or duplicated
// elsewhere in the log record.
// It should never include user-generated data, such as file contents.
//
// Required: false
optional google.protobuf.Struct request = 7;
// The status of the overall operation.
//
// Required: true
ResponseMetadata response_metadata = 8 [(buf.validate.field).required = true];
// The operation response. This may not include all response elements,
// such as those that are too large, privacy-sensitive, or duplicated
// elsewhere in the log record.
//
// Required: false
optional google.protobuf.Struct response = 9;
// Other service-specific data about the request, response, and other
// information associated with the current audited event.
//
// Required: false
optional google.protobuf.Struct metadata = 10;
}
// Authentication information for the operation.
message AuthenticationInfo {
// STACKIT principal id
//
// Required: true
string principal_id = 1 [
(buf.validate.field).required = true,
(buf.validate.field).string.min_len = 1,
(buf.validate.field).string.pattern = ".*\\S.*"
];
// The email address of the authenticated user.
// Service accounts have email addresses that can be used.
//
// Required: false
optional string principal_email = 2 [
(buf.validate.field).string.min_len = 5,
(buf.validate.field).string.max_len = 255,
(buf.validate.field).string.email = true
];
// The name of the service account used to create or exchange
// credentials for authenticating the service account making the request.
//
// Format: projects/<id>/service-accounts/<accountId>
//
// Examples:
// "projects/29b2c56f-f712-4a9c-845b-f0907158e53c/service-accounts/a606dc68-8b97-421b-89a9-116bcbd004df"
//
// Required: false
optional string service_account_name = 3 [(buf.validate.field).string.pattern = "^[a-z-]+/[a-z0-9-]+/service-accounts/[a-z0-9-]+$"];
// Identity delegation history of an authenticated service account that makes
// the request. It contains information on the real authorities that try to
// access STACKIT resources by delegating on a service account. When multiple
// authorities present, they are guaranteed to be sorted based on the original
// ordering of the identity delegation events.
//
// Required: false
repeated ServiceAccountDelegationInfo service_account_delegation_info = 4;
}
// Authorization information for the operation.
message AuthorizationInfo {
// The resource being accessed, as a REST-style string.
//
// Format: <pluralType>/<id>[/<details>]
// Where:
// Plural-Type: One from the list of supported ObjectType as plural
// Id: The identifier of the object
// Details: Optional "<key>/<id>" pairs
//
// Examples:
// "organizations/40ab14ad-b7b0-4b1c-be41-5bc820a968d1"
// "projects/7046e7b6-5ae9-441c-99fe-2cd28a5078ec/locations/_/instances/instance-20240723-174217"
// "projects/7046e7b6-5ae9-441c-99fe-2cd28a5078ec/locations/eu01/instances/instance-20240723-174217"
// "projects/7046e7b6-5ae9-441c-99fe-2cd28a5078ec/locations/eu01/vms/b6851b4e-7a9d-4973-ab0f-a80a13ee3060/ports/78f8bad4-a291-4fa3-b07f-4a1985d3dbe8"
//
// Required: true
string resource = 1 [
(buf.validate.field).required = true,
(buf.validate.field).string.pattern = "^[a-z]+/[a-z0-9-]+(?:/[a-z0-9-]+/[a-z0-9-_]+)*$"
];
// The required IAM permission.
//
// Examples:
// "resourcemanager.project.edit"
//
// Required: false
optional string permission = 2 [(buf.validate.field).string.pattern = "^[a-z-]+(?:\\.[a-z-]+)*\\.[a-z-]+$"];
// IAM permission check result.
//
// Required: false
optional bool granted = 3;
}
// This message defines the standard attribute vocabulary for STACKIT APIs.
//
// An attribute is a piece of metadata that describes an activity on a network
// service.
message AttributeContext {
// This message defines request authentication attributes. Terminology is
// based on the JSON Web Token (JWT) standard, but the terms also
// correlate to concepts in other standards.
message Auth {
// The authenticated principal. Reflects the issuer ("iss") and subject
// ("sub") claims within a JWT.
//
// Format: <sub-claim>/<iss-claim>
// Where:
// Sub-Claim: Sub-Claim from JWT with `/` percent-encoded (url-encoded)
// Issuer-Claim: Iss-Claim from JWT with `/` percent-encoded (url-encoded)
//
// Examples:
// "stackit-resource-manager-dev/https%3A%2F%2Faccounts.dev.stackit.cloud"
//
// Required: true
string principal = 1 [
(buf.validate.field).required = true,
(buf.validate.field).string.pattern = "^[a-zA-Z0-9-%._]+/[a-zA-Z0-9-%.]+$"
];
// The intended audience(s) for this authentication information. Reflects
// the audience ("aud") claim within a JWT, typically the services intended
// to receive the credential.
//
// Examples:
// ["stackit-resource-manager-dev", "stackit", "api"]
//
// Required: false
repeated string audiences = 2;
// Structured claims presented with the credential. JWTs include
// {"key": <value>} pairs for standard and private claims.
//
// The following is a subset of the standard required and optional claims that should
// typically be presented for a STACKIT JWT.
// Don't add other claims to not leak internal or personal information:
//
// {
// "aud": "stackit-resource-manager-dev",
// "email": "max@mail.schwarz",
// "iss": "https://api.dev.stackit.cloud",
// "jti": "45a196e0-480f-4c34-a592-dc5db81c8c3a"
// "sub": "cd94f01a-df2e-4456-902f-48f5e57f0b63"
// }
//
// Required: true
google.protobuf.Struct claims = 3 [(buf.validate.field).required = true];
}
enum HttpMethod {
HTTP_METHOD_UNSPECIFIED = 0;
HTTP_METHOD_OTHER = 1;
HTTP_METHOD_GET = 2;
HTTP_METHOD_HEAD = 3;
HTTP_METHOD_POST = 4;
HTTP_METHOD_PUT = 5;
HTTP_METHOD_DELETE = 6;
HTTP_METHOD_CONNECT = 7;
HTTP_METHOD_OPTIONS = 8;
HTTP_METHOD_TRACE = 9;
HTTP_METHOD_PATCH = 10;
}
// This message defines attributes for an HTTP request. If the actual
// request is not an HTTP request, the runtime system should try to map
// the actual request to an equivalent HTTP request.
message Request {
// The unique ID for a request, which can be propagated to downstream
// systems. The ID should have low probability of collision
// within a single day for a specific service.
//
// More information can be found here: https://google.aip.dev/155
//
// Format: <idempotency-key>
// Where:
// Idempotency-key: Typically consists of a id + version
//
// Examples:
// 5e3952a9-b628-4be6-ac61-b1c6eb4a110c/5
//
// Required: false
optional string id = 1;
// The (HTTP) request method, such as `GET`, `POST`.
//
// Required: true
HttpMethod method = 2 [
(buf.validate.field).required = true,
(buf.validate.field).enum.defined_only = true
];
// The (HTTP) request headers / gRPC metadata. If multiple headers share the same key, they
// must be merged according to the HTTP spec. All header keys must be
// lowercased, because HTTP header keys are case-insensitive.
//
// Internal IP-Addresses have to be removed (e.g. in x-forwarded-xxx headers).
//
// Required: true
map<string, string> headers = 3 [(buf.validate.field).required = true];
// The gRPC / HTTP URL path.
//
// Required: true
string path = 4 [
(buf.validate.field).required = true,
(buf.validate.field).string.min_len = 1,
(buf.validate.field).string.max_len = 255,
(buf.validate.field).string.pattern = ".*\\S.*"
];
// The HTTP request `Host` header value.
//
// Required: true
string host = 5 [
(buf.validate.field).required = true,
(buf.validate.field).string.min_len = 1,
(buf.validate.field).string.pattern = ".*\\S.*"
];
// The URL scheme, such as `http`, `https` or `gRPC`.
//
// Required: true
string scheme = 6 [
(buf.validate.field).required = true,
(buf.validate.field).string.min_len = 1,
(buf.validate.field).string.pattern = ".*\\S.*"
];
// The HTTP URL query in the format of "name1=value1&name2=value2", as it
// appears in the first line of the HTTP request.
// The input should be escaped to not contain any special characters.
//
// Required: false
optional string query = 7;
// The timestamp when the `destination` service receives the first byte of
// the request.
//
// Required: true
google.protobuf.Timestamp time = 8 [
(buf.validate.field).required = true,
(buf.validate.field).timestamp.lt_now = true
];
// The network protocol used with the request, such as "http/1.1",
// "spdy/3", "h2", "h2c", "webrtc", "tcp", "udp", "quic". See
// https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids
// for details.
//
// Required: true
string protocol = 9 [
(buf.validate.field).required = true,
(buf.validate.field).string.min_len = 1,
(buf.validate.field).string.pattern = ".*\\S.*"
];
// The request authentication.
//
// Required: true
Auth auth = 10 [(buf.validate.field).required = true];
}
// This message defines attributes for a typical network response. It
// generally models semantics of an HTTP response.
message Response {
// The number of items returned to the client if applicable.
//
// Required: false
optional google.protobuf.Int64Value num_response_items = 1 [(buf.validate.field).int64.gte = 0];
// The HTTP response size in bytes.
//
// Required: false
optional google.protobuf.Int64Value size = 2 [(buf.validate.field).int64.gte = 0];
// The HTTP response headers. If multiple headers share the same key, they
// must be merged according to HTTP spec. All header keys must be
// lowercased, because HTTP header keys are case-insensitive.
//
// Required: false
map<string, string> headers = 3;
// The timestamp when the "destination" service generates the first byte of
// the response.
//
// Required: true
google.protobuf.Timestamp time = 4 [
(buf.validate.field).required = true,
(buf.validate.field).timestamp.lt_now = true
];
}
}
// Metadata about the request.
message RequestMetadata {
// The IP address of the caller.
// For caller from internet, this will be public IPv4 or IPv6 address.
// For caller from a VM / K8s Service / etc, this will be the SIT proxy's IPv4 address.
//
// Required: true
string caller_ip = 1 [
(buf.validate.field).required = true,
(buf.validate.field).string.ip = true
];
// The user agent of the caller.
//
// Examples:
// "OpenAPI-Generator/1.0.0/go"
// -> The request was made by the STACKIT SDK GO client, STACKIT CLI or Terraform provider
// "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36"
// -> The request was made by a web browser.
//
// Required: true
string caller_supplied_user_agent = 2 [
(buf.validate.field).required = true,
(buf.validate.field).string.min_len = 1,
(buf.validate.field).string.max_len = 255,
(buf.validate.field).string.pattern = ".*\\S.*"
];
// This field contains request attributes like request url, time, etc.
//
// Required: true
AttributeContext.Request request_attributes = 3 [(buf.validate.field).required = true];
}
// Metadata about the response
message ResponseMetadata {
// The http or gRPC status code.
//
// Examples:
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Status
// https://grpc.github.io/grpc/core/md_doc_statuscodes.html
//
// Required: true
google.protobuf.Int32Value status_code = 1 [
(buf.validate.field).required = true,
(buf.validate.field).int32.gte = 0
];
// Short description of the error
//
// Required: false
optional string error_message = 2;
// Error details
//
// Required: false
repeated google.protobuf.Struct error_details = 3;
// This field contains response attributes like headers, time, etc.
//
// Required: true
AttributeContext.Response response_attributes = 4 [(buf.validate.field).required = true];
}
// Identity delegation history of an authenticated service account.
message ServiceAccountDelegationInfo {
// Anonymous system principal to be used when no user identity is available.
message SystemPrincipal {
// Metadata about the service that uses the service account.
//
// Required: false
optional google.protobuf.Struct service_metadata = 1;
}
// STACKIT idp principal.
message IdpPrincipal {
// STACKIT principal id
//
// Required: true
string principal_id = 1 [
(buf.validate.field).required = true,
(buf.validate.field).string.min_len = 1,
(buf.validate.field).string.pattern = ".*\\S.*"
];
// The email address of the authenticated user.
// Service accounts have email addresses that can be used.
//
// Required: true
string principal_email = 2 [
(buf.validate.field).required = true,
(buf.validate.field).string.min_len = 1,
(buf.validate.field).string.max_len = 255,
(buf.validate.field).string.pattern = ".*\\S.*"
];
// Metadata about the service that uses the service account.
//
// Required: false
optional google.protobuf.Struct service_metadata = 3;
}
// Entity that creates credentials for service account and assumes its
// identity for authentication.
oneof authority {
option (buf.validate.oneof).required = true;
// System identity
SystemPrincipal system_principal = 1;
// STACKIT IDP identity
IdpPrincipal idp_principal = 2;
}
}