// Copyright 2018 Istio Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. syntax = "proto3"; import "gogoproto/gogo.proto"; import "google/api/field_behavior.proto"; import "google/protobuf/struct.proto"; import "google/protobuf/duration.proto"; import "policy/v1beta1/value_type.proto"; package istio.policy.v1beta1; option go_package="istio.io/api/policy/v1beta1"; // AttributeManifest describes a set of Attributes produced by some component // of an Istio deployment. // // // // message AttributeManifest { // The revision of this document. Assigned by server. string revision = 1; // Name of the component producing these attributes. This can be // the proxy (with the canonical name `istio-proxy`) or the name of an // `attributes` kind adapter in Mixer. string name = 2 [(google.api.field_behavior) = REQUIRED]; // AttributeInfo describes the schema of an Istio `Attribute`. // // # Istio Attributes // // Istio uses `attributes` to describe runtime activities of Istio services. // An Istio attribute carries a specific piece of information about an activity, // such as the error code of an API request, the latency of an API request, or the // original IP address of a TCP connection. The attributes are often generated // and consumed by different services. For example, a frontend service can // generate an authenticated user attribute and pass it to a backend service for // access control purpose. // // To simplify the system and improve developer experience, Istio uses // shared attribute definitions across all components. For example, the same // authenticated user attribute will be used for logging, monitoring, analytics, // billing, access control, auditing. Many Istio components provide their // functionality by collecting, generating, and operating on attributes. // For example, the proxy collects the error code attribute, and the logging // stores it into a log. // // # Design // // Each Istio attribute must conform to an `AttributeInfo` in an // `AttributeManifest` in the current Istio deployment at runtime. An // [`AttributeInfo`][istio.policy.v1beta1] is used to define an attribute's // metadata: the type of its value and a detailed description that explains // the semantics of the attribute type. Each attribute's name is globally unique; // in other words an attribute name can only appear once across all manifests. // // The runtime presentation of an attribute is intentionally left out of this // specification, because passing attribute using JSON, XML, or Protocol Buffers // does not change the semantics of the attribute. Different implementations // can choose different representations based on their needs. // // # HTTP Mapping // // Because many systems already have REST APIs, it makes sense to define a // standard HTTP mapping for Istio attributes that are compatible with typical // REST APIs. The design is to map one attribute to one HTTP header, the // attribute name and value becomes the HTTP header name and value. The actual // encoding scheme will be decided later. message AttributeInfo { // A human-readable description of the attribute's purpose. string description = 1; // The type of data carried by this attribute. istio.policy.v1beta1.ValueType value_type = 2 [(google.api.field_behavior) = REQUIRED]; } // The set of attributes this Istio component will be responsible for producing at runtime. // We map from attribute name to the attribute's specification. The name of an attribute, // which is how attributes are referred to in aspect configuration, must conform to: // // Name = IDENT { SEPARATOR IDENT }; // // Where `IDENT` must match the regular expression `[a-z][a-z0-9]+` and `SEPARATOR` must // match the regular expression `[\.-]`. // // Attribute names must be unique within a single Istio deployment. The set of canonical // attributes are described at [here](https://istio.io/docs/reference/config/policy-and-telemetry/attribute-vocabulary/). // Attributes not in that list should be named with a component-specific suffix such as // `request.count-my.component`. map attributes = 3; } // A Rule is a selector and a set of intentions to be executed when the // selector is `true` // // The following example instructs Mixer to invoke `prometheus-handler` handler for all services and pass it the // instance constructed using the 'RequestCountByService' instance. // // ```yaml // - match: match(destination.service.host, "*") // actions: // - handler: prometheus-handler // instances: // - RequestCountByService // ``` // // // // message Rule { // Match is an attribute based predicate. When Mixer receives a // request it evaluates the match expression and executes all the associated `actions` // if the match evaluates to true. // // A few example match: // // * an empty match evaluates to `true` // * `true`, a boolean literal; a rule with this match will always be executed // * `match(destination.service.host, "ratings.*")` selects any request targeting a service whose // name starts with "ratings" // * `attr1 == "20" && attr2 == "30"` logical AND, OR, and NOT are also available string match = 1; // The actions that will be executed when match evaluates to `true`. repeated Action actions = 2; // A template for an HTTP header manipulation. Values in the template are expressions // that may reference action outputs by name. For example, if an action `x` produces an output // with a field `f`, then the header value expressions may use attribute `x.output.f` to reference // the field value: // // ```yaml // request_header_operations: // - name: x-istio-header // values: // - x.output.f // ``` // // If the header value expression evaluates to an empty string, and the operation is to either replace // or append a header, then the operation is not applied. This permits conditional behavior on behalf of the // adapter to optionally modify the headers. message HeaderOperationTemplate { // Header name literal value. string name = 1 [(google.api.field_behavior) = REQUIRED]; // Header value expressions. repeated string values = 2; // Header operation type. enum Operation { // Replace a header by name. REPLACE = 0; // Remove a header by name. Values are ignored. REMOVE = 1; // Append values to the existing header values. APPEND = 2; } // Header operation type. Default operation is to replace the value of the header by name. Operation operation = 3; } // Templatized operations on the request headers using values produced by the // rule actions. Require the check action result to be OK. repeated HeaderOperationTemplate request_header_operations = 3; // Templatized operations on the response headers using values produced by the // rule actions. Require the check action result to be OK. repeated HeaderOperationTemplate response_header_operations = 4; // $hide_from_docs // Provides the ability to add a sampling configuration for Mixer rules. This sampling // will limit the scenarios in which the `actions` of the rule are executed. The sampling will // only take place after a `match` predicate has evaluated to true. // // Default behavior is no sampling (the `actions` are executed for all requests). Sampling sampling = 5; } // Action describes which [Handler][istio.policy.v1beta1.Handler] to invoke and what data to pass to it for processing. // // The following example instructs Mixer to invoke 'prometheus-handler' handler and pass it the object // constructed using the instance 'RequestCountByService'. // // ```yaml // handler: prometheus-handler // instances: // - RequestCountByService // ``` message Action { // Fully qualified name of the handler to invoke. // Must match the `name` of a [Handler][istio.policy.v1beta1.Handler.name]. string handler = 2 [(google.api.field_behavior) = REQUIRED]; // Each value must match the fully qualified name of the // [Instance][istio.policy.v1beta1.Instance.name]s. // Referenced instances are evaluated by resolving the attributes/literals for all the fields. // The constructed objects are then passed to the `handler` referenced within this action. repeated string instances = 3 [(google.api.field_behavior) = REQUIRED]; // A handle to refer to the results of the action. string name = 4; } // An Instance tells Mixer how to create instances for particular template. // // Instance is defined by the operator. Instance is defined relative to a known // template. Their purpose is to tell Mixer how to use attributes or literals to produce // instances of the specified template at runtime. // // The following example instructs Mixer to construct an instance associated with template // 'istio.mixer.adapter.metric.Metric'. It provides a mapping from the template's fields to expressions. // Instances produced with this instance can be referenced by [Actions][istio.policy.v1beta1.Action] using name // 'RequestCountByService' // // ```yaml // - name: RequestCountByService // template: istio.mixer.adapter.metric.Metric // params: // value: 1 // dimensions: // source: source.name // destination_ip: destination.ip // ``` // // // // message Instance { // The name of this instance // // Must be unique amongst other Instances in scope. Used by [Action][istio.policy.v1beta1.Action] to refer // to an instance produced by this instance. string name = 1 [(google.api.field_behavior) = REQUIRED]; // The name of the compiled in template this instance creates instances for. For referencing non compiled-in // templates, use the `template` field instead. // // The value must match the name of the available template Mixer is built with. string compiled_template = 67794676 [(google.api.field_behavior) = REQUIRED]; // The name of the template this instance creates instances for. For referencing compiled-in // templates, use the `compiled_template` field instead. // // The value must match the name of the available template in scope. string template = 2; // Depends on referenced template. Struct representation of a // proto defined by the template; this varies depending on the value of field `template`. google.protobuf.Struct params = 3 [(google.api.field_behavior) = REQUIRED]; // Defines attribute bindings to map the output of attribute-producing adapters back into // the attribute space. The variable `output` refers to the output template instance produced // by the adapter. // The following example derives `source.namespace` from `source.uid` in the context of Kubernetes: // ```yaml // params: // # Pass the required attribute data to the adapter // source_uid: source.uid | "" // attribute_bindings: // # Fill the new attributes from the adapter produced output // source.namespace: output.source_namespace // ``` map attribute_bindings = 4; } // Handler allows the operator to configure a specific adapter implementation. // Each adapter implementation defines its own `params` proto. // // In the following example we define a `metrics` handler for the `prometheus` adapter. // The example is in the form of a Kubernetes resource: // * The `metadata.name` is the name of the handler // * The `kind` refers to the adapter name // * The `spec` block represents adapter-specific configuration as well as the connection information // // ```yaml // # Sample-1: No connection specified (for compiled in adapters) // # Note: if connection information is not specified, the adapter configuration is directly inside // # `spec` block. This is going to be DEPRECATED in favor of Sample-2 // apiVersion: "config.istio.io/v1alpha2" // kind: handler // metadata: // name: requestcount // namespace: istio-system // spec: // compiledAdapter: prometheus // params: // metrics: // - name: request_count // instance_name: requestcount.metric.istio-system // kind: COUNTER // label_names: // - source_service // - source_version // - destination_service // - destination_version // --- // # Sample-2: With connection information (for out-of-process adapters) // # Note: Unlike sample-1, the adapter configuration is parallel to `connection` and is nested inside `param` block. // apiVersion: "config.istio.io/v1alpha2" // kind: handler // metadata: // name: requestcount // namespace: istio-system // spec: // compiledAdapter: prometheus // params: // param: // metrics: // - name: request_count // instance_name: requestcount.metric.istio-system // kind: COUNTER // label_names: // - source_service // - source_version // - destination_service // - destination_version // connection: // address: localhost:8090 // --- // ``` // // // // message Handler { // Must be unique in the entire Mixer configuration. Used by [Actions][istio.policy.v1beta1.Action.handler] // to refer to this handler. string name = 1 [(google.api.field_behavior) = REQUIRED]; // The name of the compiled in adapter this handler instantiates. For referencing non compiled-in // adapters, use the `adapter` field instead. // // The value must match the name of the available adapter Mixer is built with. An adapter's name is typically a // constant in its code. string compiled_adapter = 67794676 [(google.api.field_behavior) = REQUIRED]; // The name of a specific adapter implementation. For referencing compiled-in // adapters, use the `compiled_adapter` field instead. // // An adapter's implementation name is typically a constant in its code. string adapter = 2; // Depends on adapter implementation. Struct representation of a // proto defined by the adapter implementation; this varies depending on the value of field `adapter`. google.protobuf.Struct params = 3; // Information on how to connect to the out-of-process adapter. // This is used if the adapter is not compiled into Mixer binary and is running as a separate process. Connection connection = 4; } // Connection allows the operator to specify the endpoint for out-of-process infrastructure backend. // Connection is part of the handler custom resource and is specified alongside adapter specific configuration. message Connection { // The address of the backend. string address = 2; // Timeout for remote calls to the backend. google.protobuf.Duration timeout = 3 [(gogoproto.stdduration) = true]; // Auth config for the connection to the backend. If omitted, plain text will // be used. Authentication authentication = 4; } // $hide_from_docs // Sampling provides configuration of sampling strategies for Rule actions. // Multiple sampling strategies are supported. When multiple strategies are configured, // a request must be selected by all configured sampling strategies. message Sampling { // Provides filtering of actions based on random selection per request. RandomSampling random = 1; // Provides filtering of actions based on number of requests observed within // a configured time window. RateLimitSampling rate_limit = 2; } // $hide_from_docs // RandomSampling will filter based on the comparison of a randomly-generated value // against the threshold provided. // // Example: To restrict the execution of Rule actions to only 12.5% of requests, the // `sampling_rate` would be set `12.5`. // // This sampling configuration is meant to closely match the access log RuntimeFilter configuration // [supported by Envoy](https://github.com/envoyproxy/data-plane-api/blob/master/envoy/config/filter/accesslog/v2/accesslog.proto#L113) message RandomSampling { // Specifies an attribute expression to use to override the numerator in the `percent_sampled` field. // If this value is set, but no value is found OR if that value is not a numeric value, then // the derived sampling rate will be 0 (meaning no `Action`s are executed for a `Rule`). string attribute_expression = 1; // The default sampling rate, expressed as a percentage. Defaults to 0% with a denominator // of 100. FractionalPercent percent_sampled = 2; // By default sampling will be based on the value of the request header `x-request-id`. // This behavior will cause consistent sampling across `Rule`s and for the full trace of a // request through a mesh (across hosts). If that value is not present and/or // `use_independent_randomness` is set to true, the sampling will be done based on the value of // attribute specified in `attribute_epxression`. If that attribute does not exist, the system // will behave as if the sampling rate was 0 (meaning no `Action`s are executed for a `Rule`). bool use_independent_randomness = 3; } // $hide_from_docs // RateLimitSampling provides the ability to limit the number of Rule action executions that // occur over a period of time. message RateLimitSampling { // Window in which to enforce the sampling rate. google.protobuf.Duration sampling_duration = 1 [(gogoproto.nullable)=false,(gogoproto.stdduration) = true]; // Number of entries to allow during the `sampling_duration` before sampling is enforced. int64 max_unsampled_entries = 2; // The rate at which to sample entries once the unsampled limit has been reached. Sampling will be enforced // as 1 per every `sampling_rate` entries allowed. int64 sampling_rate = 3; } // $hide_from_docs // A fractional percentage is used in cases in which for performance reasons performing floating // point to integer conversions during randomness calculations is undesirable. The message includes // both a numerator and denominator that together determine the final fractional value. // // * **Example**: 1/100 = 1%. // * **Example**: 3/10000 = 0.03%. message FractionalPercent { // Specifies the numerator. Defaults to 0. uint32 numerator = 1; // Fraction percentages support several fixed denominator values. enum DenominatorType { // 100. // // **Example**: 1/100 = 1%. HUNDRED = 0; // 10,000. // // **Example**: 1/10000 = 0.01%. TEN_THOUSAND = 1; } // Specifies the denominator. If the denominator specified is less than the numerator, the final // fractional percentage is capped at 1 (100%). DenominatorType denominator = 2; } // Authentication allows the operator to specify the authentication of // connections to out-of-process infrastructure backend. message Authentication { oneof auth_type { // Originate a TLS connection to the adapter and present an auth token // in each call for client authentication. Tls tls = 1; // Secure connections to the adapter using mutual TLS by presenting // client certificates for authentication. Mutual mutual = 2; }; } // Tls let operator specify client authentication setting when TLS is used for // connection to the backend. message Tls { // The path to the file holding additional CA certificates to well known // public certs. string ca_certificates = 1; // Specifies how to get access token for client authn and authz. oneof token_source { // The path to the file holding the auth token (password, jwt token, api // key, etc). string token_path = 2; // Oauth config to fetch access token from auth provider. OAuth oauth = 3; } // AuthHeader specifies how to pass access token with authorization header. enum AuthHeader { // Access token is passed in authorization header as what it is // (authorization: some-token). PLAIN = 0; // Access token is passed to adapter as bearer token (i.e. authorization: // bearer some-token). BEARER = 1; } // Specifies how to pass access token to the adapter backend. oneof token_type { // Access token is passed as authorization header. AuthHeader auth_header = 4; // Customized header key to hold access token, e.g. x-api-key. Token will be // passed as what it is. string custom_header = 5; } // Used to configure mixer TLS client to verify the hostname on the returned // certificates. It is also included in the client's handshake to support SNI. string server_name = 6; } // OAuth let operator specify config to fetch access token via oauth when using // TLS for connection to the backend. message OAuth { // OAuth client id for mixer. string client_id = 1 [(google.api.field_behavior) = REQUIRED]; // The path to the file holding the client secret for oauth. string client_secret = 2 [(google.api.field_behavior) = REQUIRED]; // The Resource server's token endpoint URL. string token_url = 3 [(google.api.field_behavior) = REQUIRED]; // List of requested permissions. repeated string scopes = 4; // Additional parameters for requests to the token endpoint. map endpoint_params = 5; } // Mutual let operator specify TLS configuration for Mixer as client if mutual TLS is used to // secure connection to adapter backend. message Mutual { // The path to the file holding the private key for mutual TLS. If omitted, the // default Mixer private key will be used. string private_key = 1; // The path to the file holding client certificate for mutual TLS. If omitted, the // default Mixer certificates will be used. string client_certificate = 2; // The path to the file holding additional CA certificates that are needed to // verify the presented adapter certificates. By default Mixer should already // include Istio CA certificates and system certificates in cert pool. string ca_certificates = 3; // Used to configure mixer mutual TLS client to supply server name for SNI. // It is not used to verify the hostname of the peer certificate, since // Istio verifies whitelisted SAN fields in mutual TLS. string server_name = 4; }