Custom Resource Definitions
PlainidInjector
The PlainidInjector CRD provides a mechanism to inject the PlainID Authorizer into a pod.
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: docker.io/plainid/authz-envoy-sidecar:1.6.0
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"
The following table lists the keys that should be updated in the authz-v1-plainidinjector.
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 |
EnvoyFilter
Include the following filter configuration in your deployment (e.g., in envoy-filter.yaml
), after applying the injector.
Sample envoy-filter.yaml:
apiVersion: networking.istio.io/v1
kind: EnvoyFilter
metadata:
name: plainid-authz-filter
# The EnvoyFilter must be in the same namespace as the workload.
namespace: protected
spec:
# Selects the pod(s) where this filter will be applied.
workloadSelector:
labels:
app: my-protected-app # <-- Label of the app to protect
configPatches:
- applyTo: HTTP_FILTER
match:
context: SIDECAR_INBOUND
listener:
filterChain:
filter:
name: "envoy.filters.network.http_connection_manager"
subFilter:
name: "envoy.filters.http.router"
# The port number MUST match your service's targetPort.
portNumber: 7000 # <-- Service port your app listens on
patch:
operation: INSERT_BEFORE
value:
name: envoy.ext_authz
typed_config:
"@type": "type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthz"
transport_api_version: V3
failure_mode_allow: false
grpc_service:
google_grpc:
# e.g., "plainid-service.auth-namespace.svc.cluster.local:9001"
target_uri: 127.0.0.1:50051
stat_prefix: plainid_ext_authz
timeout: 1s
with_request_body:
max_request_bytes: 8192
allow_partial_message: true
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.
*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:
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, Should be set
resourceTypes:
- name: ExternalForIDP
actionPath: "$.header.X-Action"
assetPath: "$.header.X-Asset"
environments:
amount: "$.body.amount"
account: "$.path[2]"
url: $.path.[0]
options:
includeDetails: true
includeAccessPolicy: true
includeAssetAttributes: true
includeIdentity: true
includeDenyReason: true
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 in the Developer Portal.
Example
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
JSONPath | Value based on above request |
---|---|
$.body.amount |
50 |
$.param.test |
true |
$.path[2] |
0000001 |
$.header.x-forwarded-for |
10.2.3.1 |