johnpoth / spec

Specification for binding services to k8s applications

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Service Binding Specification for Kubernetes

Today in Kubernetes, the exposure of secrets for connecting applications to external services such as REST APIs, databases, event buses, and many more is manual and bespoke. Each service provider suggests a different way to access their secrets, and each application developer consumes those secrets in a custom way to their applications. While there is a good deal of value to this flexibility level, large development teams lose overall velocity dealing with each unique solution. To combat this, we already see teams adopting internal patterns for how to achieve this application-to-service linkage.

This specification aims to create a Kubernetes-wide specification for communicating service secrets to applications in an automated way. It aims to create a widely applicable mechanism but without excluding other strategies for systems that it does not fit easily. The benefit of Kubernetes-wide specification is that all of the actors in an ecosystem can work towards a clearly defined abstraction at the edge of their expertise and depend on other parties to complete the chain.

  • Application Developers expect their secrets to be exposed consistently and predictably.
  • Service Providers expect their secrets to be collected and exposed to users consistently and predictably.
  • Platforms expect to retrieve secrets from Service Providers and expose them to Application Developers consistently and predictably.

The pattern of Service Binding has prior art in non-Kubernetes platforms. Heroku pioneered this model with Add-ons, and Cloud Foundry adopted similar ideas with their Services. Other open source projects like the Open Service Broker aim to help with this pattern on those non-Kubernetes platforms. In the Kubernetes ecosystem, the CNCF Sandbox Cloud Native Buildpacks project has proposed a buildpack-specific specification exclusively addressing the application developer portion of this pattern.

Community

The Service Binding Specification for Kubernetes project is a community lead effort. A bi-weekly working group call is open to the public. Discussions occur here on GitHub and on the #bindings-discuss channel in the Kubernetes Slack.

If you catch an error in the specification’s text, or if you write an implementation, please let us know by opening an issue or pull request at our GitHub repository.

Behavior within the project is governed by the Contributor Covenant Code of Conduct.



Notational Conventions

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here.

The key words "unspecified", "undefined", and "implementation-defined" are to be interpreted as described in the rationale for the C99 standard.

An implementation is not compliant if it fails to satisfy one or more of the MUST, MUST NOT, REQUIRED, SHALL, or SHALL NOT requirements for the protocols it implements. An implementation is compliant if it satisfies all the MUST, MUST NOT, REQUIRED, SHALL, and SHALL NOT requirements for the protocols it implements.

Terminology definition

Duck Type
Any type that meets the contract defined in a specification, without being an instance of a specific concrete type. For example, for specification that requires a given key on status, any resource that has that key on its status regardless of its kind would be considered a duck type of the specification.
Service
Any software that exposes functionality. Examples include a database, a message broker, an application with REST endpoints, an event stream, an Application Performance Monitor, or a Hardware Security Module.
Application
Any process, running within a container. Examples include a Spring Boot application, a NodeJS Express application, or a Ruby Rails application. Note: This is different than an umbrella application as defined by the Kubernetes SIG, which refers to a set of micro-services.
Service Binding
The act of or representation of the action of providing information about a Service to an Application
ConfigMap
A Kubernetes ConfigMap
Secret
A Kubernetes Secret

Provisioned Service

A Provisioned Service resource MUST define a .status.binding which is a LocalObjectReference-able (containing a single field name) to a Secret. The Secret MUST be in the same namespace as the resource. The Secret data SHOULD contain a type entry with a value that identifies the abstract classification of the binding. The Secret type (.type verses .data.type) SHOULD reflect this value as service.binding/{type}, replacing {type} with the Secret data type. It is RECOMMENDED that the Secret data also contain a provider entry with a value that identifies the provider of the binding. The Secret data MAY contain any other entry. To facilitate discoverability, it is RECOMMENDED that a CustomResourceDefinition exposing a Provisioned Service add service.binding/provisioned-service: "true" as a label.

Extensions and implementations MAY define additional mechanisms to consume a Provisioned Service that does not conform to the duck type.

Resource Type Schema

status:
  binding:
    name:  # string

Example Resource

...
status:
  ...
  binding:
    name: production-db-secret

Well-known Secret Entries

Other than the recommended type and provider entries, there are no other reserved Secret entries. In the interests of consistency, if a Secret includes any of the following entry names, the entry value MUST meet the specified requirements:

Name Requirements
host A DNS-resolvable host name or IP address
port A valid port number
uri A valid URI as defined by RFC3986
username A string-based username credential
password A string-based password credential
certificates A collection of PEM-encoded X.509 certificates, representing a certificate chain used in mTLS client authentication
private-key A PEM-encoded private key used in mTLS client authentication

Secret entries that do not meet these requirements MUST use different entry names.

Example Secret

apiVersion: v1
kind: Secret
metadata:
  name: production-db
type: service.binding/mysql
stringData:
  type: mysql
  provider: bitnami
  host: localhost
  port: 3306
  username: root
  password: root

Application Projection

A Binding Secret MUST be volume mounted into a container at $SERVICE_BINDING_ROOT/<binding-name> with directory names matching the name of the binding. Binding names MUST match [a-z0-9\-\.]{1,253}. The $SERVICE_BINDING_ROOT environment variable MUST be declared and can point to any valid file system location.

The Secret data MUST contain a type entry with a value that identifies the abstract classification of the binding. The Secret type (.type verses .data.type) MUST reflect this value as service.binding/{type}, replacing {type} with the Secret data type. It is RECOMMENDED that the Secret data also contain a provider entry with a value that identifies the provider of the binding. The Secret data MAY contain any other entry.

The name of a secret entry file name SHOULD match [a-z0-9\-\.]{1,253}. The contents of a secret entry may be anything representable as bytes on the file system including, but not limited to, a literal string value (e.g. db-password), a language-specific binary (e.g. a Java KeyStore with a private key and X.509 certificate), or an indirect pointer to another system for value resolution (e.g. vault://production-database/password).

The collection of files within the directory MAY change between container launches. The collection of files within the directory SHOULD NOT change during the lifetime of the container.

Example Directory Structure

$SERVICE_BINDING_ROOT
├── account-database
│   ├── type
│   ├── provider
│   ├── uri
│   ├── username
│   └── password
└── transaction-event-stream
    ├── type
    ├── connection-count
    ├── uri
    ├── certificates
    └── private-key

Service Binding

A Service Binding describes the connection between a Provisioned Service and an Application Projection. It MUST be codified as a concrete resource type with API version service.binding/v1alpha2 and kind ServiceBinding. Multiple Service Bindings can refer to the same service. Multiple Service Bindings can refer to the same application. For portability, the schema MUST comply to the exemplar CRD found here.

Restricting service binding to resources within the same namespace is strongly RECOMMENDED. Implementations that choose to support cross-namespace service binding SHOULD provide a security model that prevents attacks like privilege escalation and secret enumeration, as well as a deterministic way to declare target namespaces.

A Service Binding resource MUST define a .spec.application which is an ObjectReference-like declaration. A ServiceBinding MAY define the application reference by-name or by-label selector. A name and selector MUST NOT be defined in the same reference. A Service Binding resource MUST define a .spec.service which is an ObjectReference-like declaration to a Provisioned Service-able resource. Extensions and implementations MAY allow additional kinds of applications and services to be referenced.

The Service Binding resource MAY define .spec.application.containers, as a list of integers or strings, to limit which containers in the application are bound. Binding to a container is opt-in, unless .spec.application.containers is undefined then all containers MUST be bound. For each item in the containers list:

  • if the value is an integer (${containerInteger}), the container matching by index (.spec.template.spec.containers[${containerInteger}]) MUST be bound. Init containers MUST NOT be bound
  • if the value is a string (${containerString}), a container or init container matching by name (.spec.template.spec.containers[?(@.name=='${containerString}')] or .spec.template.spec.initContainers[?(@.name=='${containerString}')]) MUST be bound
  • values that do not match a container or init container SHOULD be ignored

A Service Binding Resource MAY define a .spec.mappings which is an array of Mapping objects. A Mapping object MUST define name and value entries. The value of a Mapping MUST be handled as a Go Template exposing binding Secret keys for substitution. The executed output of the template MUST be added to the Secret exposed to the resource represented by application as the key specified by the name of the Mapping. If the name of a Mapping matches that of a Provisioned Service Secret key, the value from Mapping MUST be used for binding.

A Service Binding Resource MAY define a .spec.env which is an array of EnvMapping. An EnvMapping object MUST define name and key entries. The key of an EnvMapping MUST refer to a binding Secret key name including any key defined by a Mapping. The value of this Secret entry MUST be configured as an environment variable on the resource represented by application.

A Service Binding resource MUST define .status.conditions which is an array of Condition objects as defined in meta/v1 Condition. At least one condition containing a type of Ready MUST be defined. The Ready condition SHOULD contain appropriate values defined by the implementation. As label selectors are inherently queries that return zero-to-many resources, it is RECOMMENDED that ServiceBinding authors use a combination of labels that yield a single resource, but implementors MUST handle each matching resource as if it was specified by name in a distinct ServiceBinding resource. Partial failures MUST be aggregated and reported on the binding status's Ready condition. A Service Binding resource SHOULD reflect the secret projected into the application as .status.binding.name.

Resource Type Schema

apiVersion: service.binding/v1alpha2
kind: ServiceBinding
metadata:
  name:                 # string
  generation:           # int64, defined by the Kubernetes control plane
  ...
spec:
  name:                 # string, optional, default: .metadata.name
  type:                 # string, optional
  provider:             # string, optional

  application:          # ObjectReference-like
    apiVersion:         # string
    kind:               # string
    name:               # string, mutually exclusive with selector
    selector:           # metav1.LabelSelector, mutually exclusive with name
    containers:         # []intstr.IntOrString, optional

  service:              # Provisioned Service resource ObjectReference-like
    apiVersion:         # string
    kind:               # string
    name:               # string

  mappings:             # []Mapping, optional
  - name:               # string
    value:              # string

  env:                  # []EnvMapping, optional
  - name:               # string
    key:                # string

status:
  binding:              # LocalObjectReference, optional
    name:               # string
  conditions:           # []metav1.Condition containing at least one entry for `Ready`
  observedGeneration:   # int64

Minimal Example Resource

apiVersion: service.binding/v1alpha2
kind: ServiceBinding
metadata:
  name: account-service
spec:
  application:
    apiVersion: apps/v1
    kind:       Deployment
    name:       online-banking

  service:
    apiVersion: com.example/v1alpha1
    kind:       AccountService
    name:       prod-account-service

status:
  conditions:
  - type:   Ready
    status: 'True'
    reason: 'Projected'
    message: ''
    lastTransitionTime: '2021-01-20T17:00:00Z'

Label Selector Example Resource

apiVersion: service.binding/v1alpha2
kind: ServiceBinding
metadata:
  name: online-banking-frontend-to-account-service
spec:
  name: account-service

  application:
    apiVersion: apps/v1
    kind:       Deployment
    selector:
      matchLabels:
        app.kubernetes.io/part-of: online-banking
        app.kubernetes.io/component: frontend

  service:
    apiVersion: com.example/v1alpha1
    kind:       AccountService
    name:       prod-account-service

status:
  conditions:
  - type:   Ready
    status: 'True'
    reason: 'Projected'
    message: ''
    lastTransitionTime: '2021-01-20T17:00:00Z'

Mappings Example Resource

apiVersion: service.binding/v1alpha2
kind: ServiceBinding
metadata:
  name: account-service
spec:
  application:
    apiVersion: apps/v1
    kind:       Deployment
    name:       online-banking

  service:
    apiVersion: com.example/v1alpha1
    kind:       AccountService
    name:       prod-account-service

  mappings:
  - name:  accountServiceUri
    value: https://{{ urlquery .username }}:{{ urlquery .password }}@{{ .host }}:{{ .port }}/{{ .path }}

status:
  binding:
    name: prod-account-service-projection
  conditions:
  - type:   Ready
    status: 'True'
    reason: 'Projected'
    message: ''
    lastTransitionTime: '2021-01-20T17:00:00Z'

Environment Variables Example Resource

apiVersion: service.binding/v1alpha2
kind: ServiceBinding
metadata:
  name: account-service
spec:
  application:
    apiVersion: apps/v1
    kind:       Deployment
    name:       online-banking

  service:
    apiVersion: com.example/v1alpha1
    kind:       AccountService
    name:       prod-account-service

  mappings:
  - name:  accountServiceUri
    value: https://{{ urlquery .username }}:{{ urlquery .password }}@{{ .host }}:{{ .port }}/{{ .path }}

  env:
  - name: ACCOUNT_SERVICE_HOST
    key:  host
  - name: ACCOUNT_SERVICE_USERNAME
    key:  username
  - name: ACCOUNT_SERVICE_PASSWORD
    key:  password
  - name: ACCOUNT_SERVICE_URI
    key:  accountServiceUri

status:
  binding:
    name: prod-account-service-projection
  conditions:
  - type:   Ready
    status: 'True'
    reason: 'Projected'
    message: ''
    lastTransitionTime: '2021-01-20T17:00:00Z'

Reconciler Implementation

A Reconciler implementation for the ServiceBinding type is responsible for binding the Provisioned Service binding Secret into an Application. The Secret referred to by .status.binding on the resource represented by service MUST be mounted as a volume on the resource represented by application.

If a .spec.name is set, the directory name of the volume mount MUST be its value. If a .spec.name is not set, the directory name of the volume mount SHOULD be the value of .metadata.name.

If the $SERVICE_BINDING_ROOT environment variable has already been configured on the resource represented by application, the Provisioned Service binding Secret MUST be mounted relative to that location. If the $SERVICE_BINDING_ROOT environment variable has not been configured on the resource represented by application, the $SERVICE_BINDING_ROOT environment variable MUST be set and the Provisioned Service binding Secret MUST be mounted relative to that location. A RECOMMENDED value to use is /bindings.

The $SERVICE_BINDING_ROOT environment variable MUST NOT be reset if it is already configured on the resource represented by application.

If a .spec.type is set, the type entry in the binding Secret MUST be set to its value overriding any existing value. If a .spec.provider is set, the provider entry in the binding Secret MUST be set to its value overriding any existing value.

Ready Condition Status

If the modification of the Application resource is completed successfully, the Ready condition status MUST be set to True. If the modification of the Application resource is not completed successfully the Ready condition status MUST NOT be set to True.

Direct Secret Reference

There are scenarios where an appropriate resource conforming to the Provisioned Service duck-type does not exist, but there is a Secret available for binding. This feature allows a ServiceBinding resource to directly reference a Secret.

When the .spec.service.kind attribute is Secret and .spec.service.apiVersion is v1, the .spec.service.name attribute MUST be treated as .status.binding.name for a Provisioned Service.

Direct Secret Reference Example Resource

apiVersion: service.binding/v1alpha2
kind: ServiceBinding
metadata:
  name: account-service

spec:
  application:
    apiVersion: apps/v1
    kind:       Deployment
    name:       online-banking

  service:
    apiVersion: v1
    kind:       Secret
    name:       prod-account-service-secret

status:
  binding:
    name: prod-account-service-reference
  conditions:
  - type:   Ready
    status: 'True'
    reason: 'Projected'
    message: ''
    lastTransitionTime: '2021-01-20T17:00:00Z'

Application Resource Mapping

An Application Resource Mapping describes how to apply Service Binding transformations to an Application Projection. It MUST be codified as a concrete resource type with API version service.binding/v1alpha2 and kind ClusterApplicationResourceMapping. For portability, the schema MUST comply to the exemplar CRD found here.

An Application Resource Mapping MUST define its name using CRD syntax (<plural>.<group>) for the resource that it defines a mapping for. An Application Resource Mapping MUST define a .spec.versions which is an array of Version objects. A Version object must define a version entry that represents a version of the mapped resource. The version entry MAY contain a * wildcard which indicates that this mapping should be used for any version that does not have a mapping explicitly defined for it. A Version object MAY define .containers, as an array of strings containing JSONPath, that describes the location of []Container arrays in the target resource. A Version object MAY define .envs, as an array of strings containing JSONPath, that describes the location of []EnvVar arrays in the target resource. A Version object MAY define .volumeMounts, as an array of strings containing JSONPath, that describes the location of []VolumeMount arrays in the target resource. A Version object MUST define .volumes, as a string containing JSONPath, that describes the location of []Volume arrays in the target resource.

If an Application Resource Mapping defines containers, it MUST NOT define .envs and .volumeMounts. If an Application resources does not define containers, it MUST define .envs and .volumeMounts.

Resource Type Schema

apiVersion: service.binding/v1alpha2
kind: ClusterApplicationResourceMapping
metadata:
  name:                 # string
  generation:           # int64, defined by the Kubernetes control plane
  ...
spec:
  versions:             # []Version
  - version:            # string
    containers:         # []string, optional
    envs:               # []string, optional
    volumeMounts:       # []string, optional
    volumes:            # string

Container-based Example Resource

apiVersion: service.binding/v1alpha2
kind: ClusterApplicationResourceMapping
metadata:
 name:  cronjobs.batch
spec:
  versions:
  - version: "*"
    containers:
    - .spec.jobTemplate.spec.template.spec.containers
    - .spec.jobTemplate.spec.template.spec.initContainers
    volumes: .spec.jobTemplate.spec.template.spec.volumes

Element-based Example Resource

apiVersion: service.binding/v1alpha2
kind: ClusterApplicationResourceMapping
metadata:
 name:  cronjobs.batch
spec:
  versions:
  - version: "*"
    envs:
    - .spec.jobTemplate.spec.template.spec.containers[*].env
    - .spec.jobTemplate.spec.template.spec.initContainers[*].env
    volumeMounts:
    - .spec.jobTemplate.spec.template.spec.containers[*].volumeMounts
    - .spec.jobTemplate.spec.template.spec.initContainers[*].volumeMounts
    volumes: .spec.jobTemplate.spec.template.spec.volumes

PodSpec-able (Default) Example Resource

apiVersion: service.binding/v1alpha2
kind: ClusterApplicationResourceMapping
metadata:
  name: deployments.apps
spec:
  versions:
  - version: "*"
    containers:
    - .spec.template.spec.containers
    - .spec.template.spec.initContainers
    volumes: .spec.template.spec.volumes

Reconciler Implementation

A reconciler implementation MUST support mapping to PodSpec-able resources without defining a Application Resource Mapping for those types. If no Application Resource Mapping exists for the ServiceBinding application resource type and the application resource is not PodSpec-able, the reconciliation MUST fail.

If a ClusterApplicationResourceMapping defines containers, the reconciler MUST first resolve a set of candidate locations in the application resource addressed by the ServiceBinding using the Container type (.envs, .volumeMounts) for all available containers and then filter that collection by the ServiceBinding .spec.application.containers filter before applying the appropriate modification.

If a ClusterApplicationResourceMapping defines .envs and .volumeMounts, the reconciler MUST first resolve a set of candidate locations in the application resource addressed by the ServiceBinding for all available containers and then filter that collection by the ServiceBinding .spec.application.containers filter before applying the appropriate modification.

If a ServiceBinding specifies a .spec.applications.containers value, and the value contains an Int-based index, that index MUST be used to filter the first entry in the .containers list and all other entries in those lists are ineligible for mapping. If a ServiceBinding specifies a .spec.applications.containers value, and the value contains an string-based index that index MUST be used to filter all entries in the .containers list. If a ServiceBinding specifies a .spec.applications.containers value and ClusterApplicationResourceMapping for the mapped type defines .envs and .volumeMounts, the reconciler MUST fail to reconcile.

A reconciler MUST apply the appropriate modification to the application resource addressed by the ServiceBinding as defined by .volumes.

Extensions

Extensions are optional additions to the core specification as defined above. Implementation and support of these specifications are not required in order for a platform to be considered compliant. However, if the features addressed by these specifications are supported a platform MUST be in compliance with the specification that governs that feature.

Binding Secret Generation Strategies

Many services, especially initially, will not be Provisioned Service-compliant. These services will expose the appropriate binding Secret information, but not in the way that the specification or applications expect. Users should have a way of describing a mapping from existing data associated with arbitrary resources and CRDs to a representation of a binding Secret.

To handle the majority of existing resources and CRDs, Secret generation needs to support the following behaviors:

  1. Extract a string from a resource
  2. Extract an entire ConfigMap/Secret refrenced from a resource
  3. Extract a specific entry in a ConfigMap/Secret referenced from a resource
  4. Extract entries from a collection of objects, mapping keys and values from entries in a ConfigMap/Secret referenced from a resource
  5. Map each value to a specific key

While the syntax of the generation strategies are specific to the system they are annotating, they are based on a common data model.

Model Description
path A template represention of the path to an element in a Kubernetes resource. The value of path is specified as JSONPath. Required.
objectType Specifies the type of the object selected by the path. One of ConfigMap, Secret, or string (default).
elementType Specifies the type of object in an array selected by the path. One of sliceOfMaps, sliceOfStrings, string (default).
sourceKey Specifies a particular key to select if a ConfigMap or Secret is selected by the path. Specifies a value to use for the key for an entry in a binding Secret when elementType is sliceOfMaps.
sourceValue Specifies a particular value to use for the value for an entry in a binding Secret when elementType is sliceOfMaps

OLM Operator Descriptors

OLM Operators are configured by setting the specDescriptor and statusDescriptor entries in the ClusterServiceVersion with mapping descriptors.

Descriptor Examples

The following examples refer to this resource definition.

apiVersion: apps.kube.io/v1beta1
kind: Database
metadata:
  name: my-cluster
spec:
  ...

status:
  bootstrap:
  - type: plain
    url: myhost2.example.com
    name: hostGroup1
  - type: tls
    url: myhost1.example.com:9092,myhost2.example.com:9092
    name: hostGroup2
  data:
    dbConfiguration: database-config     # ConfigMap
    dbCredentials: database-cred-Secret  # Secret
    url: db.stage.ibm.com
  1. Mount an entire Secret as the binding Secret

    - path: data.dbCredentials
      x-descriptors:
      - urn:alm:descriptor:io.kubernetes:Secret
      - service.binding
  2. Mount an entire ConfigMap as the binding Secret

    - path: data.dbConfiguration
      x-descriptors:
      - urn:alm:descriptor:io.kubernetes:ConfigMap
      - service.binding
  3. Mount an entry from a ConfigMap into the binding Secret

    - path: data.dbConfiguration
      x-descriptors:
      - urn:alm:descriptor:io.kubernetes:ConfigMap
      - service.binding:certificate:sourceKey=certificate
  4. Mount an entry from a ConfigMap into the binding Secret with a different key

    - path: data.dbConfiguration
      x-descriptors:
      - urn:alm:descriptor:io.kubernetes:ConfigMap
      - service.binding:timeout:sourceKey=db_timeout
  5. Mount a resource definition value into the binding Secret

    - path: data.uri
      x-descriptors:
      - service.binding:uri
  6. Mount a resource definition value into the binding Secret with a different key

    - path: data.connectionURL
      x-descriptors:
      - service.binding:uri
  7. Mount the entries of a collection into the binding Secret selecting the key and value from each entry

    - path: bootstrap
      x-descriptors:
      - service.binding:endpoints:elementType=sliceOfMaps:sourceKey=type:sourceValue=url

Non-OLM Operator and Resource Annotations

Non-OLM Operators are configured by adding annotations to the Operator's CRD with mapping configuration. All Kubernetes resources are configured by adding annotations to the resource.

Annotation Examples

The following examples refer to this resource definition.

apiVersion: apps.kube.io/v1beta1
kind: Database
metadata:
  name: my-cluster
spec:
  ...

status:
  bootstrap:
  - type: plain
    url: myhost2.example.com
    name: hostGroup1
  - type: tls
    url: myhost1.example.com:9092,myhost2.example.com:9092
    name: hostGroup2
  data:
    dbConfiguration: database-config     # ConfigMap
    dbCredentials: database-cred-Secret  # Secret
    url: db.stage.ibm.com
  1. Mount an entire Secret as the binding Secret
    “service.binding":
      ”path={.status.data.dbCredentials},objectType=Secret”
    
  2. Mount an entire ConfigMap as the binding Secret
    service.binding”:
      "path={.status.data.dbConfiguration},objectType=ConfigMap”
    
  3. Mount an entry from a ConfigMap into the binding Secret
    “service.binding/certificate”:
      "path={.status.data.dbConfiguration},objectType=ConfigMap,sourceKey=certificate"
    
  4. Mount an entry from a ConfigMap into the binding Secret with a different key
    “service.binding/timeout”:
      “path={.status.data.dbConfiguration},objectType=ConfigMap,sourceKey=db_timeout”
    
  5. Mount a resource definition value into the binding Secret
    “service.binding/uri”:
      "path={.status.data.url}"
    
  6. Mount a resource definition value into the binding Secret with a different key
    “service.binding/uri":
      "path={.status.data.connectionURL}”
    
  7. Mount the entries of a collection into the binding Secret selecting the key and value from each entry
    “service.binding/endpoints”:
      "path={.status.bootstrap},elementType=sliceOfMaps,sourceKey=type,sourceValue=url"
    

Role-Based Access Control (RBAC)

Kubernetes clusters often utilize Role-based access control (RBAC) to authorize subjects to perform specific actions on resources. When operating in a cluster with RBAC enabled, the service binding reconciler needs permission to read resources that provisioned a service and write resources that services are projected into. This extension defines a means for third-party CRD authors and cluster operators to expose resources to the service binding reconciler. Cluster operators MAY impose additional access controls beyond RBAC.

For Cluster Operators and CRD Authors

Cluster operators and CRD authors MAY opt-in resources to service binding by defining a ClusterRole with a label matching service.binding/controller=true. For Provisioned Service resources the get, list, and watch verbs MUST be granted. For Application resources resources the get, list, watch, update, and patch verbs MUST be granted.

Example Resource

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: awesome-service-bindings
  labels:
    service.binding/controller: "true" # matches the aggregation rule selector
rules:
# for Provisioned Service resources only
- apiGroups:
  - awesome.example.com
  resources:
  - awesomeservices
  verbs:
  - get
  - list
  - watch
# for Application resources (also compatible with Provisioned Service resources)
- apiGroups:
  - awesome.example.com
  resources:
  - awesomeapplications
  verbs:
  - get
  - list
  - watch
  - update
  - patch

For Service Binding Implementors

Service binding reconciler implementations MUST define an aggregated ClusterRole with a label selector matching the label service.binding/controller=true. This ClusterRole MUST be bound (RoleBinding for a single namespace or ClusterRoleBinding if cluster-wide) to the subject the service binding reconciler runs as, typically a ServiceAccount.

Example Resource

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: ...
aggregationRule:
  clusterRoleSelectors:
  - matchLabels:
      service.binding/controller: "true"
rules: [] # The control plane automatically fills in the rules

About

Specification for binding services to k8s applications

License:Apache License 2.0


Languages

Language:Go 93.0%Language:Makefile 7.0%