Istio
    • 10 Mar 2024
    • 12 Minutes to read
    • Dark
      Light
    • PDF

    Istio

    • Dark
      Light
    • PDF

    Article Summary

    Istio Sidecar

    Sidecar Installation

    It is recommended that you use Helm Chart v3.8.0 to install and configure a Sidecar solution on Kubernetes.

    Istio is an open source, service mesh implementation that controls the communication to and between multiple service components. Istio is responsible for determining for example, which pods running service A can reach pods running service B.

    Authorization Policies need to consider the Identities that are operating or wish to operate these services, and what they are trying to do. So, while Istio successfully supports the enforcement of access control policies, the question remains who is allowed, how and when and where this permissions is given or denied.

    The Istio Authorizer runs on the Istio Service Mesh, delivering high performance as it enforces/authorizes the Organization's Access Policies. The PlainID Sidecar supports the Istio Service Mesh.

    When installing and using an Istio Sidecar Authorizer, it is recommended that you install and configure the Sidecar solution on Kubernetes using Helm Chart. For more information on downloading and configuring Istio, see the Helm Chart in the Admin Portal.

    In addition to running the Sidecar itself, the Helm Chart is responsible for installing and configuring the Sidecar to integrate with other components. Helm v 3.8.0 is required to properly install and configure the Sidecar solution with your Kubernetes cluster.

    Prerequisites

    The following applications are required to install and configure Istio for use with the Platform:

    • Kubernetes 1.15+
    • Istio 1.15
    • Helm 3.8.0+

    Obtaining the Authorizer Package/Bundle:

    • For PlainID v.4.x: Contact PlainID Tech Support to request the Istio Authorizer download package.
    • For PlainID Authorization Platform v5.x. (for more information, contact our Technical Support team for the Authorizer Deployment Download.

    The Policy Authorizer Package Content

    FileDescriptionShould be updated
    /plainid-sidecar/templates/crds.yamlK8s Custom Resource DefinitionsNo
    /plainid-sidecar/templates/manager.yamlDeployment configuration for authz-operator (plainid-controller-manager)No
    /plainid-sidecar/templates/namespace.yamlDeployment configuration for authz-operator (plainid-controller-manager)Optional
    /plainid-sidecar/templates/rbac.yamK8s Namespace configuration for authz-operator (plainid-controller-manager)Optional
    /plainid-sidecar/templates/serviceAccount.yamlK8s Service Account configurationOptional
    /plainid-sidecar/templates/webhook.yamlPlainID Mutating Webhook configurationNo
    /plainid-sidecar/Chart.yamlContains information about the Helm ChartYes
    /plainid-sidecar/filter.yamlEnvoy configuration example (EnvoyFilter kind)Yes
    /plainid-sidecar/values.yamlThe default configuration values for this chart (AuthZ Operator and Sidecar settings)Yes
    /samples/authz_v1_plainidinjector.yamlAuthZ Sidecar Pod-Injection configurationNo
    /samples/sidecar-echo.yamlAuthZ Sidecar configuration example with settingsYes
    /images.txtList of PlainID AuthZ Operator and Sidecar images with tags (versions)No

    Installation

    1. Obtain the Istio Sidecar Authorizer zip archive from PlainID Support.
    2. Unpack the Authorizer archive.
    3. Configure authz image versions:
    • Update the appVersion value in Chart.yaml file: Set tag of the authz-operator image from the images.txt file.
    • Update spec.container.image value tag in samples/authz_v1_plainidinjector.yaml file: Set tag of authz-envoy-sidecar image from file images.txt
    1. Update specific settings in values.yaml.
    2. Update specific settings of the PlainidSidecar kind (example in samples/sidecar-echo.yaml).
    3. Install Helm if not installed (image.png Helm | Helm ).
    4. Install using the Helm Chart:

    helm install sidecar-test plainid-sidecar

    1. Label target namespace for PlainID Injection.

    kubectl label namespace default pid-injection=enabled

    1. Deploy authz-sidecar injector.

    kubectl apply -f samples/authz_v1_plainidinjector.yaml

    1. Deploy authz-sidecar configuration (PlainidSidecar kind).

    kubectl apply -f samples/sidecar-echo.yaml

    1. Restart a pod with the target microservice, so authz-sidecar will be injected.

    kubectl delete pod echo

    Sidecar Workflow

    In addition to running the Sidecar itself, the Helm Chart is responsible for installing and configuring the Sidecar to integrate with other components. Helm v 3.8.0 is required to properly install and configure the Sidecar solution with your Kubernetes cluster.

    image.png

    The benefit to this approach is that all decisions are made locally on the same server as the microservice and require no network hops. This delivers a higher level of availability and performance.

    Following is a typical workflow for integration of the PlainID sidecar and the Authorization Platform.

    1. The client sends their access/ID token in the request header.
    2. The request is intercepted by the Envoy Proxy and passed to the PlainID Sidecar.
    3. The PlainID sidecar is another container that is automatically injected to the pods, similar to the Envoy proxy.
    4. The PlainID sidecar makes a Permit/Deny decision, based on the defined policies. The PlainID sidecar can base this decision on the request URL, request header, and request body.
    5. In addition, there is an option to inject Entitlements/additional information to the request header, to provide specific access data to the service.
    6. Optionally, the sidecar approaches the Authorization Platform.
    7. If the Authorization Decision is Permit, the Envoy proxy passes the request to the service container. Otherwise, If the Authorization Decision is Deny, the request never reaches the actual service container and a 403 response is returned immediately.
      image.png

    For more information about the Permit/Deny end point, see Authorization APIs.

    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.

    NameDescriptionExample
    config.params.mgrOperator service name and portplainid-controller-manager-discover.plainid-system:16000
    config.params.SKIP_TLS_VERIFYSkip 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.

    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:
              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:
          clientId: client_id_goes_here           # Mandatory: From the Platform UI
          clientSecret: client_secret_goes_here   # From the Platform UI, if no Secret store used 
          entityTypeid: jwt
          plainidUrl: https://demo.plainid.cloud  # Mandatory: PDP URL, Should be set
          resourceTypes:                          # Asset mappings example (only for PDP API v1-4)
            - name: Accounts
              assetPath: $.path[4]
            - name: Loans
          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"
    

    sidecar-echo.yaml

    NameDescriptionExample
    workloadSelectorThis 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.allowedList of allowed jwt issuers Ability to define mappings between iss claim and the actual issuer.ID mapping is not required omit mapped value- name: demo mapped: https://demo.plainid.cloud/auth/realms/demo - name: demo.plainid.cloud
    jwt.userClaimstring: JsonPath of the user unique identifier$.user.preferred_username[0]
    jwt.headerstring: Header name of the jwtauthorization
    jwt.validateJwtBool: Indicates if jwt should be validated (use for development purposes only)true
    jwt.algsList: Algorithms (RS256 by default if not set)- ES256 - RS256
    mode.decision *Bool: PERMIT/DENY Mode * only one mode should be set to truetrue
    mode.entitlement *Bool: Header Injection mode * only one mode should be set to truetrue
    mode.resolution *Bool: Header injection mode Query format * only one mode should be set to truetrue
    mode.denyOnEmptyBool: DENY transaction when no Policy fits the access request.false
    mode.format0 – full access token 1 – short access token – action with list of assets. Ex. {"Accounts":{"assets":{"get":["0008","0001","0004","0002"],"view":["0008","0001","0004","0002"]}}} 2 – short access token – asset with list of actions Ex. {"0001":["view","get"],"0002":["view","get"],"0004":["view","get"],"0008":["view","get"]}0
    runtime.clientIdApplication ClientIdFrom the Platform UI.
    runtime.clientSecretApplication SecretFrom the Platform UI.
    runtime.entityTypeidEntity TypeFrom Policy Manager Management UI.
    runtime.plainidUrlRuntime (pdp) base URLhttp://pdp:8000
    runtime.resourceTypesRefer to ResourceTypes****
    Runtime.environmentsenvironment variable and the values from the requestamount: $.body.amount

    ResourceTypes

    NameDescriptionExample
    actionPathThe Request part that is considered as an Action. Default HTTP Method See Request Parts Locations$.body.action
    assetPathRequest part considered as Asset ID. See Request Parts Locations$.path[4]
    nameTemplate name to useAccounts
    virtualMapThe mapping between Template Attributes and Request partsvirtualMap: userid: $.path[1] userid - is an attribute in plainid template $.path[1] – is JsonPath of the request part

    Request Parts Locations

    Request PartJsonPath root objectNotes
    Body$.body
    URI$.pathArray of URI parts Full URI - $.path[0] First Part - $.path[1]
    Headers$.headerAll 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 Policy Manager in the Developer Portal.

    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.

    NameDescriptionExample
    config.params.mgrconfig.params.mgrplainid-controller-manager- discover.plainid-system:16000
    config.params.SKIP_TLS_VERIFYSkip TLS certificate verification (for dev environments)false

    Operator

    KeyExplanationOptional Value/Example
    namespaceThe namespace where the operator will be createdplainid-system
    replicasNumber of replicas1
    debugThe debug statetrue/false
    imageThe image repository of the operatorgcr.io/plainid-presales/authz-operator

    Redis

    KeyExplanationOptional Value/Example
    imageRedis image repositoryredis
    masterhostHostname of the master Redis instanceMaster.redis.example.com
    passMaster password*****

    Auth

    KeyExplanationOptional Value/Example
    filefull path to a file with a secret key (same key as in Runtime configuration)secret:/keys/key
    ississuer or JWT claim (same issuer as in Runtime configuration)ruleengine
    expJWT 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:

    MethodExample
    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"


    Was this article helpful?