--- title: "Istio Configuration" slug: "istio-configuration" updated: 2025-08-21T14:39:26Z published: 2025-08-21T14:39:26Z canonical: "docs.plainid.io/istio-configuration" --- > ## Documentation Index > Fetch the complete documentation index at: https://docs.plainid.io/llms.txt > Use this file to discover all available pages before exploring further. # Istio Configuration ## Sidecar Configuration The sidecar configuration can be set per service/app to fit its specific enforcement requirements. The sidecar configuration is done by custom resource definitions that are part of the installation process. To apply the configuration, run the following command: `kubectl apply -f authz-v1-plainid-injector.yaml` The configuration will be applied immediately and no redeployment of the application is required. ## Custom Resource Definitions ### Sample authz-v1-plainidinjector.yaml ``` apiVersion: authz.plainid.io/v1 kind: PlainidInjector metadata: name: plainidinjector-sample spec: volume: name: podinfo downwardAPI: items: - path: "labels" fieldRef: fieldPath: metadata.labels - path: "annotations" fieldRef: fieldPath: metadata.annotations container: name: plainid-authz image: gcr.io/plainid-presales/authz-envoy-sidecar:1.0.1 resources: requests: cpu: "0.05" memory: "50M" limits: cpu: "0.2" imagePullPolicy: Always ports: - containerPort: 50051 - containerPort: 9090 volumeMounts: - name: podinfo mountPath: /config env: - name: POD_NAME valueFrom: fieldRef: apiVersion: v1 fieldPath: metadata.name - name: POD_NAMESPACE valueFrom: fieldRef: apiVersion: v1 fieldPath: metadata.namespace config: params: mgr: plainid-controller-manager-discover.plainid-system:16000 SKIP_TLS_VERIFY: "true" ``` ### authz-v1-plainidinjector.yaml The following table lists the keys that should be updated in the plainidinjectorconfig.yaml. All remaining text should be the default value. | Name | Description | Example | | --- | --- | --- | | config.params.mgr | Operator service name and port | plainid-controller-manager-discover.plainid-system:16000 | | config.params.SKIP_TLS_VERIFY | Skip TLS certificate verification (for dev environments) | false | ## PlainidSidecar The PlainidSidecar CRD provides a mechanism to customize the Sidecar configuration generated by the operator. Use the PlainidSidecar CRD to modify values for certain fields and define the specific behavior of the Sidecar. *Note: This feature must be used with care, as incorrect configurations could potentially destabilize the Sidecar and the service. * Apply configuration by workload selectors and namespaces. The following example applies to all workloads with the label **app:echo** in a namespace **test**. **Generating a Token to Authenticate via Runtime** The Runtime supports token-based authentication using idpSources and pdpAuth (in the runtime section below). Ensure that the `idpId` in `runtime` matches the `id` in the `idpSources`. ### Sample sidecar-echo.yaml Following is an example of a microservice sidecar configuration file. ``` apiVersion: authz.plainid.io/v1 kind: PlainidSidecar metadata: name: echo spec: workloadSelector: labels: app: echo sidecarConfig: matchers: # API Matchers section (Optional) - match: /echo/bypass# Request path pattern method: # Request methods - POST - GET bypass: true # Bypass request (ignore all validations and authorization) - match: /echo/:abc runtime: # Specific runtime configuratoin for matching requests entityTypeid: jwt cacheTime: 11s mode: # Specific mode configuratoin for matching requests entitlement: true format: 5 flat: false denyOnEmpty: true - match: /echo runtime: metadata: "{\"combinedMultiValues\": true}" entityTypeid: jwt cacheTime: 11s clientId: client_id_goes_here clientSecret: client_secret_goes_here environments: amount: "$.body.amount" account: "$.body.account" url: $.path.[0] mode: resolution: true format: 5 flat: false denyOnEmpty: true runtime: # apiVersion: v5 pdpAuth: clientId: "PDP_CLIENT_ID" authMode: 2 idpId: auth1 clientSecretLocation: 1 cacheTime: 1s entityTypeid: User2 entityId: "2" plainidUrl: https://demo.plainid.cloud # Mandatory: PDP URL resourceTypes: - name: ExternalForIDP actionPath: "$.header.X-Action" assetPath: "$.header.X-Asset" environments: amount: "$.body.amount" account: "$.path[2]" url: $.path.[0] jwt: # Mandatory: External request JWT configuration header: authorization allowed: - name: demo.plainid.cloud # Mandatory: JWT Issuer example - name: demo # Mandatory: JWT Issuer mapping example in case of JWT issuer do not match an issuer provided by Auth service mapped: https://demo.plainid.cloud/auth/realms/demo userClaim: "$.user.preferred_username[0]" validateJwt: true algs: # List of supported Signing Algorythms (RS256 by default if not set) - ES256 - RS256 mode: # Mandatory: Operation mode, ONLY ONE OF SHOULD BE TRUE: decision/entitlement/resolution/denyOnEmpty decision: true # PERMIT/DENY Mode entitlement: false # Header Injection mode resolution: false # Header injection mode Query format denyOnEmpty: false # DENY transaction when no policy fits the access request. format: 2 logger: logLevel: debug detailedLog: false format: text tlsSkip: true grpc: servicePort: "7001" idpSources: - id: auth1 url: https://idp.url clientId: idp_client_id clientSecret: idp_client_secret additionalParameters: audience: idp_audience grant_type: client_credentials asyncRefresh: false ``` ### Parameters | Name | Description | Example | | --- | --- | --- | | workloadSelector | This criteria is used to select the specific set of pods on which this configuration should be applied. If omitted, the set of patches in this configuration will be applied to all workload instances in the same namespace. | `app: echo` | | jwt.allowed | List of allowed jwt issuers. Ability to define mappings between `iss` claim and the actual issuer. ID mapping is not required if omitted. | - name: demo mapped: `<https://demo.plainid.cloud/auth/realms/demo>` - name: demo.plainid.cloud | | jwt.userClaim | JsonPath of the user unique identifier | `$.user.preferred_username[0]` | | jwt.header | Header name of the JWT | `authorization` | | jwt.validateJwt | Boolean: Indicates if JWT should be validated (use for development purposes only) | `true` | | jwt.algs | List: Algorithms (RS256 by default if not set) | - `ES256` - `RS256` | | mode.decision * | `PERMIT`/`DENY` Mode * only one mode should be set to true | `true` | | mode.entitlement * | Boolean: Header Injection mode * only one mode should be set to true | `true` | | mode.resolution * | Boolean: Header injection mode Query format * only one mode should be set to true | `true` | | mode.denyOnEmpty | Boolean: DENY transaction when no Policy fits the access request. | `false` | | mode.format | 0 – full access token 1 – short access token – action with list of assets. Ex. `{"Accounts":{"assets":{"get":["0008","0001"],"view":["0008","0001"]}}}` 2 – short access token – asset with list of actions Ex. `{"0001":["view","get"],"0002":["view","get"]}` | `0` | | runtime.clientId | Application ClientId | From Platform UI. | | runtime.clientSecret | Application Secret | From Platform UI. | | runtime.pdpAuth.clientId | Client ID used for PDP authentication | `PDP_CLIENT_ID` | | runtime.pdpAuth.authMode | Authentication mode (numeric value) | `2` | | runtime.pdpAuth.idpId | Identifier of the IdP used for PDP authentication | `auth1` | | runtime.pdpAuth.clientSecretLocation | Location type of the client secret (numeric value) | `1` | | runtime.cacheTime | Duration to cache PDP responses | `1s` | | runtime.entityTypeid | Entity Type identifier | `User2` | | runtime.entityId | Unique identifier of the Entity | `2` | | runtime.plainidUrl | Runtime (PDP) base URL (mandatory) | `https://demo.plainid.cloud` | | runtime.resourceTypes | List of resource types with action and asset mappings | - name: `ExternalForIDP` actionPath: `$.header.X-Action` assetPath: `$.header.X-Asset` | | runtime.environments | Environment variable and the values from the request | `amount: $.body.amount` | | runtime.passIncomingJwt | Boolean: To define whether to pass the IDP JWT as-is to the PDP | `false` | | runtime.options | PDP Runtime response fine-tune options | | | runtime.options.includeDetails | Boolean: Determines whether to include the details of the Access Decision in the response. | `false` | | runtime.options.includeAccessPolicy | Boolean: Show/hide the name of the Policy in the response that has granted the specified access. | `false` | | runtime.options.includeAssetAttributes | Boolean: Show/hide the asset attribute of the assets in the response. | `false` | | runtime.options.includeIdentity | Boolean: Show/hide the identity attribute of the identity in the response. | `false` | | runtime.options.includeDenyReason | Boolean: Show/hide the reason for the denial of access in the response. | `false` | | idpSources.id | Identifier for the IdP configuration | `auth1` | | idpSources.url | Base URL of the IdP | `https://idp.url` | | idpSources.clientId | Client ID for the IdP | `idp_client_id` | | idpSources.clientSecret | Client Secret for the IdP | `idp_client_secret` | | idpSources.additionalParameters | Additional key-value parameters required for authentication | audience: `idp_audience` grant_type: `client_credentials` | | idpSources.asyncRefresh | Boolean: Determines if token refresh should be performed asynchronously | `false` | --- ### ResourceTypes | Name | Description | Example | | --- | --- | --- | | actionPath | The Request part that is considered as an Action. Default HTTP Method See Request Parts Locations | $.body.action | | assetPath | Request part considered as Asset ID. See Request Parts Locations | $.path[4] | | name | Template name to use | Accounts | | virtualMap | The mapping between Template Attributes and Request parts | virtualMap: userid: $.path[1] userid - is an attribute in plainid template $.path[1] – is JsonPath of the request part | ### Request Parts Locations | Request Part | JsonPath root object | Notes | | --- | --- | --- | | Body | $.body | | | URI | $.path | Array of URI parts Full URI - $.path[0] First Part - $.path[1] | | Headers | $.header | All headers will be converted to lowercase | | Query Parameters | $.param | | | User Attributes | $.user | | ### Operation Modes The Platform sidecar supports three operation modes: - **Decision** – a basic Permit/Deny mode that enables or blocks the transaction. - **Entitlements** – an advanced mode that can enrich the request header with a list of entitlements or any authorization supporting data. - **Resolution** – an advanced mode that can enrich the request header with a “policy resolution” decision - JSON or SQL filtering for data. For more information on these options, refer to the [Authorization APIs](https://docs.plainid.io/apidocs/authorization-apis) in the Developer Portal. ### Request Sample | | | | --- | --- | | Request URL | POST `http://localhost:18000/echo/0000001/assets?test=true` | | Request Header | Tenant: t1 X-Forwarded-For: 10.2.3.1 | | Request Body | `{"amount":50, "type": "transaction", "asset" : 1234}` | ### Mapping Sample | JSON Path | Value based on request sample | | --- | --- | | $.body.amount | 50 | | $.param.test | true | | $.path[2] | 0000001 | | $.header.x-forwarded-for | 10.2.3.1 | ## Additional Configuration Information | Option | Explanation | | --- | --- | | JWT Issuers and mapping | In jwt.allowed, you can either define an issuer URI or you can define an issuer alias with a mapped value. Define an issuer URI: `jwt:` `header: authorization` `allowed:` `- name: demo.plainid.cloud` Example of an issuer alias with a mapped value: `jwt:` `header: authorization` `allowed:` `- name: demo` `mapped: https://demo.plainid.cloud/auth/realms/demo` You can also use a combination (as shown in the configuration above) | ::: ## Override Default Configuration The **helm install** command accepts parameters to override default configuration values inline or that are defined in a file. 1. Example – To override the configuration found in the file: `cat override-values.yml` ``` runtime: debugLevel: info replicas: 5 ``` `helm install sidecar-test1 ./ --values override-values.yml` 1. Add a namespace label to instruct PlainID to automatically inject the sidecar when you deploy your application later: `kubectl label namespace default pid-injection=enabled` 1. Instruct the Istio proxy to send the traffic to the PlainID sidecar for authorization. The following example (found in filter.yaml) inserts an http ext_authz filter in the default namespace: ``` apiVersion: v1 items: - apiVersion: networking.istio.io/v1alpha3 kind: EnvoyFilter metadata: generation: 1 name: demo-filter namespace: default spec: configPatches: - applyTo: HTTP_FILTER match: context: SIDECAR_INBOUND listener: filterChain: filter: name: envoy.http_connection_manager subFilter: name: envoy.router portNumber: 7000 patch: operation: INSERT_BEFORE value: name: envoy.ext_authz typed_config: '@type': type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthz failure_mode_allow: false grpc_service: google_grpc: stat_prefix: ext_authz target_uri: 127.0.0.1:50051 timeout: 2s transport_api_version: V3 with_request_body: allow_partial_message: true max_request_bytes: 1024 pack_as_bytes: true # workloadSelector: # annotations: # plainid.io/inject: "yes" kind: List metadata: resourceVersion: "" selfLink: "" ``` ## Sample values.yaml *Note: For versions 4.x, you should remove the following from the values.yaml configuration file:* **pdpAPIVersion: v5 #Optional: PDP Runtime API v5 integration** ``` # Please Generate Public key , Private key and Certificate chain # based on the documentation provided by PlainID and place in certs folder # File names should match the example files in the chart image: pullPolicy: Always imagePullSecrets: - name: cr-creds nameOverride: "" fullnameOverride: "" serviceAccount: plainid podSecurityContext: {} operator: image: gcr.io/plainid-presales/authz-operator namespace: plainid-system resources: limits: cpu: 100m memory: 100Mi requests: cpu: 100m memory: 20Mi replicas: 1 debug: true redis: local: true image: redis port: 6379 pass: "" tls: false masterhost: test-plainid-redis-ro.plainid # Administration point address securityContext: capabilities: drop: - ALL runAsNonRoot: true runAsUser: 1000610001 webhook: enabled: true selfCert: true auth: # Optional: Secret store configuration file: "/keys/key" iss: "ruleengine" exp: 10s pdpAPIVersion: v5 #Optional: PDP Runtime API v5 integration authorizer: id: test-authorizer # Mandatory: Should be updated version: 1.2.3 moreVolumes: # Optional: Extra volumes configuration - name: key-config configMap: name: key-config nodeSelector: {} tolerations: [] affinity: {} ``` **authz-v1-plainidinjector.yaml** The following table lists the keys that should be updated in the plainidinjectorconfig.yaml. All remaining text should be the default value. | Name | Description | Example | | --- | --- | --- | | config.params.mgr | config.params.mgr | plainid-controller-manager- discover.plainid-system:16000 | | config.params.SKIP_TLS_VERIFY | Skip TLS certificate verification (for dev environments) | false | #### Operator | Key | Explanation | Optional Value/Example | | --- | --- | --- | | namespace | The namespace where the operator will be created | plainid-system | | replicas | Number of replicas | 1 | | debug | The debug state | true/false | | image | The image repository of the operator | gcr.io/plainid-presales/authz-operator | #### Redis | Key | Explanation | Optional Value/Example | | --- | --- | --- | | image | Redis image repository | redis | | masterhost | Hostname of the master Redis instance | Master.redis.example.com | | pass | Master password | ***** | #### Auth | Key | Explanation | Optional Value/Example | | --- | --- | --- | | file | full path to a file with a secret key (same key as in Runtime configuration) | secret:/keys/key | | iss | issuer or JWT claim (same issuer as in Runtime configuration) | ruleengine | | exp | JWT expiration (10s by default if not set) | 10s | ## GRPC Support The PlainID sidecar supports GRPC (Google Remote Procedure Call) parsing. This capability can be achieved in different ways: - Auto learning - Providing a Protocol Buffer (protobuf) descriptor file ## Auto Learning To support auto learning, the Application Developer should be enabled GRPC reflection on the server side (backend). In the sidecar configuration YAML, the service port should be defined. Example ``` grpc: servicePort: "7001" ``` ## Providing a protobuf Descriptor File Providing a protobuf descriptor file can be accomplished in one of the following ways: | Method | Example | | --- | --- | | Create a protobuf descriptor file from proto definition. | protoc --descriptor_set_out=demo.pb demo.proto | | Create a new container image from plainid-authz-sidecar. | **Create a new Dockerfile** FROM gcr.io/plainid-presales/authz-envoy-sidecar:1.0.1;, ADD demo.pb /proto/demo.pb **Build a new image**: docker build -t authz-envoy-sidecar:1.0.1-pb, **Push the new image** to the relevant registry | ## Multiple Descriptors It is possible to include multiple descriptors. You can use the same image for all the services. To use the same image for multiple descriptors: 1. Change the PlainidInjector yaml to provide a new image tag. 2. In the plainidsidecar.yaml file, provide the path to the relevant descriptor file. `grpc: protoFile: "/proto/demo.pb"`