{"id":26059777,"url":"https://github.com/orange-cloudfoundry/osb-cmdb","last_synced_at":"2025-08-02T04:34:27.944Z","repository":{"id":37936916,"uuid":"213967042","full_name":"orange-cloudfoundry/osb-cmdb","owner":"orange-cloudfoundry","description":"A configuration management db for Open Service Broker API broker implementations","archived":false,"fork":false,"pushed_at":"2023-03-06T03:56:56.000Z","size":27181,"stargazers_count":14,"open_issues_count":42,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-04-11T07:07:00.007Z","etag":null,"topics":["cloudfoundry","inventory-management","k8s","osbapi"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/orange-cloudfoundry.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.adoc","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.adoc","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2019-10-09T16:22:00.000Z","updated_at":"2023-03-22T03:41:54.000Z","dependencies_parsed_at":"2025-04-11T06:50:56.182Z","dependency_job_id":"64e7ee77-1ce1-4f40-9ad8-4619f2eb6cdd","html_url":"https://github.com/orange-cloudfoundry/osb-cmdb","commit_stats":null,"previous_names":[],"tags_count":36,"template":false,"template_full_name":null,"purl":"pkg:github/orange-cloudfoundry/osb-cmdb","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/orange-cloudfoundry%2Fosb-cmdb","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/orange-cloudfoundry%2Fosb-cmdb/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/orange-cloudfoundry%2Fosb-cmdb/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/orange-cloudfoundry%2Fosb-cmdb/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/orange-cloudfoundry","download_url":"https://codeload.github.com/orange-cloudfoundry/osb-cmdb/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/orange-cloudfoundry%2Fosb-cmdb/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":268334620,"owners_count":24233793,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-02T02:00:12.353Z","response_time":74,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cloudfoundry","inventory-management","k8s","osbapi"],"created_at":"2025-03-08T13:28:23.360Z","updated_at":"2025-08-02T04:34:27.918Z","avatar_url":"https://github.com/orange-cloudfoundry.png","language":"Java","readme":"\n## Osb-cmdb\n\n[![CircleCI Build status](https://circleci.com/gh/orange-cloudfoundry/osb-cmdb.svg?style=svg)](https://app.circleci.com/pipelines/github/orange-cloudfoundry/osb-cmdb)\n\nThis project provides a configuration management for Open Service Broker API broker implementations, enabling sharing of service brokers among multiple OSB client platoforms. See [orange-cloudfoundry/paas-templates#492](https://github.com/orange-cloudfoundry/paas-templates/issues/492) for more background around use-cases and considered alternatives.\n\n\u003c!-- \n TOC generated during https://github.com/ekalinin/github-markdown-toc\ncat README.md | /home/guillaume/public-code/github-markdown-toc/gh-md-toc - \n--\u003e\n\n * [Functional overview](#functional-overview)\n * [Getting started](#getting-started)\n    * [Deploying](#deploying)\n    * [Increasing log levels dynamically](#increasing-log-levels-dynamically)\n    * [Accessing http traces](#accessing-http-traces)\n    * [Accessing other production-ready actuator endpoints](#accessing-other-production-ready-actuator-endpoints)\n    * [Catalog management](#catalog-management)\n       * [Static catalog](#static-catalog)\n       * [Dynamic catalog](#dynamic-catalog)\n    * [Typical CMDB content](#typical-cmdb-content)\n    * [Assigning roles and permissions](#assigning-roles-and-permissions)\n    * [Metadata attached to backing services](#metadata-attached-to-backing-services)\n       * [Metadata for CF OSB client](#metadata-for-cf-osb-client)\n       * [Metadata for K8S OSB client](#metadata-for-k8s-osb-client)\n    * [Refreshing OSB client cache through Maintenance-info](#refreshing-osb-client-cache-through-maintenance-info)\n * [Technical details](#technical-details)\n    * [osb-cmdb osb client calls requirements](#osb-cmdb-osb-client-calls-requirements)\n       * [Future support for additional meta-data](#future-support-for-additional-meta-data)\n    * [OSB-api extension (x-osb-cmdb) used with backing service brokers](#osb-api-extension-x-osb-cmdb-used-with-backing-service-brokers)\n    * [Dashboard AuthN and AuthZ support (WIP)](#dashboard-authn-and-authz-support-wip)\n       * [Discovery of the OIDC endpoint](#discovery-of-the-oidc-endpoint)\n       * [Discovery of the OAuth client_id and client_secret to provision](#discovery-of-the-oauth-client_id-and-client_secret-to-provision)\n       * [Dashboard AuthN using OIDC](#dashboard-authn-using-oidc)\n       * [Dashboard AuthZ using CF service instance permission](#dashboard-authz-using-cf-service-instance-permission)\n       * [Dashboard AuthZ using K8S API](#dashboard-authz-using-k8s-api)\n       * [Interaction flow diagram](#interaction-flow-diagram)\n * [Contributing](#contributing)\n    * [Credits](#credits)\n    * [Design documentation](#design-documentation)\n    * [Circle ci tests](#circle-ci-tests)\n    * [Acceptance tests](#acceptance-tests)\n    * [Releasing](#releasing)\n\t\t\t\n### Functional overview\n\nThe following diagram presents a functional overview of the ocb-cdmb feature scope\n![Overview diagram](osb-cmdb/overview.png)\n\nThe features are supported by coarse gain components used by osb-cmdb:\n\n![Osb cmdb component diagrams](osb-cmdb/Osb-cmdb-zoom.png)\n\nOsb-cmdb is an OSB facade that provides the following features to service admins:\n* maintain an inventory of service instances and service keys consummed by OSB clients\n   * list/find/delete service instances and service bindings (per osb client/ service definition or osb-client context, see metadata)\n   * display usage analytics on consumed service instances/bindings (e.g. through grafana dashboard)\n   * receive alerts upon failed osb requests  \n* manage service offering visbility per OSB client\n* manage authentication (including credentials rotation) per OSB client, independently of underlying brokers\n\nIn addition, Osb-cmdb handle OSB API viriants such as K8S svcat duplicated calls, protecting service broker authors from having to deal with each OSB api variations. See [#17](https://github.com/orange-cloudfoundry/osb-cmdb-spike/issues/17) for more details.\n\nThe osb-cdmb service broker translates received osb calls into equivalent CF CC API calls\n\nOSB API endpoint | eq CF CLI UX\n------------ | -------------\nGET /v2/catalog | cf marketplace\nPUT /v2/service_instances/:instance_id | cf create-space ; cf create-service; cf7 set-label; cf7 set-annotation\nGET /v2/service_instances/:instance_id/last_operation | cf service\nGET /v2/service_instances/:instance_id | cf service (WIP)\nPATCH /v2/service_instances/:instance_id | cf update-service\nDELETE /v2/service_instances/:instance_id | cf delete-service\nPUT /v2/service_instances/:instance_id/service_bindings/:binding_id | cf create-service-key\nGET /v2/service_instances/:instance_id/service_bindings/:binding_id/last_operation | cf get-service-key (WIP)\nGET /v2/service_instances/:instance_id/service_bindings/:binding_id | cf get-service-key\nDELETE /v2/service_instances/:instance_id/service_bindings/:binding_id | cf delete-service-key\n\n### Getting started\n\n#### Deploying\n\nOsb-cmdb ships as a spring-boot jar which is configured using properties.\n\n```bash         \ncurl -L https://github.com/orange-cloudfoundry/osb-cmdb-spike/releases/download/v0.9.0/osb-cmdb-0.9.0.jar -o ./osb-cmdb.jar \njava \\\n -Dspring.cloud.appbroker.deployer.cloudfoundry.api-host=api.redacted-domain.org \\\n -Dspring.cloud.appbroker.deployer.cloudfoundry.api-port=443 \\\n -Dspring.cloud.appbroker.deployer.cloudfoundry.default-org=osb-cmdb-services-org-client-0 \\\n -Dspring.cloud.appbroker.deployer.cloudfoundry.default-space=p-mysql \\\n -Dspring.cloud.appbroker.deployer.cloudfoundry.username=redacted \\\n -Dspring.cloud.appbroker.deployer.cloudfoundry.password=redacted \\\n -Dspring.security.user.name=user \\\n -Dspring.security.user.password=password \\\n -Dosbcmdb.admin.user=user \\\n -Dosbcmdb.admin.password=password \\\n -Dosbcmdb.dynamic-catalog.enabled=true \\\n -Dosbcmdb.dynamic-catalog.catalog.services.suffix=suffix \\\n -Dosbcmdb.dynamic-catalog.catalog.services.excludeBrokerNamesRegexp=\".*cmdb.*\" \\\n -Dosbcmdb.broker.propagateMetadataAsCustomParam=true \\\n -Dosbcmdb.broker.hideMetadataCustomParamInGetServiceInstanceEndpoint=true \\\n -Dlogging.level.cloudfoundry-client=DEBUG \\\n -Dlogging.level.cloudfoundry-client.operations=DEBUG \\\n -Dlogging.level.org.springframework.cloud.appbroker=debug \\\n -Dlogging.level.org.springframework.cloud.appbroker.deployer.cloudfoundry=debug \\\n -Dlogging.level.org.springframework.cloud.servicebroker=debug \\\n    -jar ./osb-cmdb.jar \n```\n\nOsb-cmdb adds support for additional properties which are illustrated below. Source of truth is associated unit tests, e.g. `SecurityConfigTest`\n\nOsb-cmdb requires two users auth to be configured:\n* `spring.security.user`: used for OSB API calls\n* `osbcmdb.admin`: used to access sensitive supportability endpoints (powered by springboot actuators)\n\nOsb-Cmdb expects to be deployed once per OSB client, each having its own basic authentication, its own brokered services catalog, and backend services organization.\n\n#### Increasing log levels dynamically\n\nIn production like in acceptance tests, use spring boot actuator logger to dynamically increase log levels,  \n \n```bash\ncurl -kv https://admin:password@test-broker-app-create-instance-with-service-keys.redacted-domain/actuator/loggers/cloudfoundry-client.wire -X POST -H 'Content-Type: application/json' -d '{\"configuredLevel\": \"TRACE\"}'\n```\n\n\nWith the following log levels\n\nlogger | level \n-- | --\ncloudfoundry-client.operations | debug \ncloudfoundry-client.request | debug \ncloudfoundry-client.response | debug \ncloudfoundry-client.wire | trace \n\nWe observe wire traces such as  \n\n```\n20-04-2020 16:46:35.395 [cloudfoundry-client-epoll-4] DEBUG cloudfoundry-client.request.request - GET    /v2/spaces/TEST-SPACE-GUID/service_instances?q=name:instance-id\u0026page=1\u0026return_user_provided_service_instances=true\n20-04-2020 16:46:35.401 [cloudfoundry-client-epoll-4] TRACE cloudfoundry-client.wire.log - [id: 0x5cc929b8, L:/127.0.0.1:44870 - R:localhost/127.0.0.1:8080] READ: 574B\n         +-------------------------------------------------+\n         |  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f |\n+--------+-------------------------------------------------+----------------+\n|00000000| 48 54 54 50 2f 31 2e 31 20 32 30 30 20 4f 4b 0d |HTTP/1.1 200 OK.|\n|00000010| 0a 4d 61 74 63 68 65 64 2d 53 74 75 62 2d 49 64 |.Matched-Stub-Id|\n|00000020| 3a 20 39 35 39 35 34 65 66 30 2d 62 34 66 36 2d |: 95954ef0-b4f6-|\n|00000030| 34 33 61 38 2d 61 39 63 35 2d 36 35 39 66 39 63 |43a8-a9c5-659f9c|\n|00000040| 37 61 33 36 64 37 0d 0a 56 61 72 79 3a 20 41 63 |7a36d7..Vary: Ac|\n|00000050| 63 65 70 74 2d 45 6e 63 6f 64 69 6e 67 2c 20 55 |cept-Encoding, U|\n|00000060| 73 65 72 2d 41 67 65 6e 74 0d 0a 43 6f 6e 74 65 |ser-Agent..Conte|\n|00000070| 6e 74 2d 45 6e 63 6f 64 69 6e 67 3a 20 67 7a 69 |nt-Encoding: gzi|\n|00000080| 70 0d 0a 54 72 61 6e 73 66 65 72 2d 45 6e 63 6f |p..Transfer-Enco|\n|00000090| 64 69 6e 67 3a 20 63 68 75 6e 6b 65 64 0d 0a 53 |ding: chunked..S|\n|000000a0| 65 72 76 65 72 3a 20 4a 65 74 74 79 28 39 2e 34 |erver: Jetty(9.4|\n|000000b0| 2e 32 37 2e 76 32 30 32 30 30 32 32 37 29 0d 0a |.27.v20200227)..|\n[...]\n```\n\n#### Accessing http traces\n\nOsb-cmdb exposes springboot [actuator http traces](https://docs.spring.io/spring-boot/docs/current/reference/html/production-ready-features.html#production-ready-http-tracing) through the last 100 requests stored in memory. Load the following endpoint in your browser: `https://admin:password@osb-cmdb-broker-1.redacted-domain/actuator/httptrace`\n\n#### Accessing other production-ready actuator endpoints\n\nLoad the following endpoint in your browser: `https://admin:password@osb-cmdb-broker-1.redacted-domain/actuator/` to get the currently list of actuator endpoints enabled.\n\n#### Catalog management\n\nBacking services register with osb-cmdb using the CF CLI commands for [managing service brokers](https://docs.cloudfoundry.org/services/managing-service-brokers.html), i.e `cf create-service-broker SERVICE_BROKER USERNAME PASSWORD URL` and then enabling the plans on the backing service organization (configured with the `spring.cloud.appbroker.deployer.cloudfoundry.default-org` property) associated with each osb-cmdb deployment `cf enable-service-access SERVICE [-b BROKER] [-p PLAN] [-o ORG]`.\n\nOsb-cmdb operators might consider using terraform with the [cloudfoundry-community/terraform-provider-cf](https://github.com/cloudfoundry-community/terraform-provider-cf) for using a declarative approach, see [cloudfoundry_service_broker](https://github.com/cloudfoundry-community/terraform-provider-cf/blob/master/docs/resources/service_broker.md) and [cloudfoundry_service_access](https://github.com/cloudfoundry-community/terraform-provider-cf/blob/master/docs/resources/service_plan_access.md) resources\n\n\n##### Static catalog\n\nOsb-cmdb supports a statically configured catalog of brokered services, by setting `osbcmdb.dynamic-catalog.enabled=false`, and configuring the spring-cloud-open-service-broker catalog.\n\nFollowing is an example of a simple [spring-cloud-open-service-broker catalog configuration](https://docs.spring.io/spring-cloud-open-service-broker/docs/3.1.1.RELEASE/reference/html5/#providing-a-catalog-using-properties) (without detailed catalog customization)\n\n```yaml\n#### Manual catalog and brokered service configuration\n  spring:\n    cloud:\n      openservicebroker:\n        catalog:\n          services:\n            - name: p-mysql-cmdb\n              id: ebca66fd-461d-415b-bba3-5e379d671c88\n              description: A useful service\n              bindable: true\n              plan_updateable: true\n              tags:\n                - example\n              plans:\n                - name: 10mb\n                  id: p-mysql-cmdb-10mb\n                  description: A standard plan\n                  free: true\n                - name: 20mb\n                  id: p-mysql-cmdb-20mb\n                  description: A standard plan\n                  free: true\n```\n\n\n\n##### Dynamic catalog\n\nWith large marketplace being brokered, manually maintaining the catalog might be a tedious task.\n\nOsb-Cmdb brings the feature of dynamic catalog generation. This feature is enabled by default, and can be opted-out if necessary. \n\nAt start up, the broker will fetch the service definitions from the target CF instance, as visible from the default organization and space (the equivalent of the `cf marketplace` command). For now service plan visibility is not fetched.\n\nAs a result, a catalog of Brokered services is generated with a one-to-one mapping between brokered services and backing services. \nThe following properties can be used to tune this mapping:\n\n```yaml\n  osbcmdb:\n    dynamic-catalog:\n      enabled: \"true\" #Turned on by default. Enables dynamic catalog. Catalog and brokered services properties \n      catalog:\n        services:\n          suffix: \"-cmdb\" #Suffix to add each service definition\n          excludeBrokerNamesRegexp: \".*cmdb.*\" # Excludes broker names matching this regexp. Good to excluding osb-cmdb itself to avoid brokering itself. \n```\n\nAdditionally, the generated catalog is dumped on disk onto `/tmp/osb-cmdb-dynamicCatalog.yml` (see org.springframework.cloud.appbroker.autoconfigure.ServiceConfigurationYamlDumper)\n\nThis can be used as a baseline for manually tuned catalog when supported tunings in automated generation are insufficient.  \n\nThe following table further documents the options and their default values:\n\nproperty name | default value | description  \n-- | -- | -- \nosbcmdb.dynamic-catalog.enabled | true | enables dynamic catalog when set to true \nosbcmdb.dynamic-catalog.catalog.services.suffix| null| when set, adds a suffix to every service definition names \nosbcmdb.dynamic-catalog.catalog.services.excludeBrokerNamesRegexp| null | when set, exclude service brokers from dynamic catalog whose name match the specified java regular expression \n\n\n\n#### Typical CMDB content\n\nThe following figure displays a hierarchical cloudfoundry org/space/service instance|binding|key organization before osb-cmdb startups and apply its `SpacePerServiceDefinition` strategy \n\n```\n01    ├── osb-cmdb-backend-services-org-client-0 \n02    │   ├── default \n04    └── osb-cmdb-smoke-test-brokered-services-org-client-0 \n05        ├── smoke-tests      \n06        └── default          \n```\n\n* 01 holds backend service instances resulting from the client. Expected to be available at startup\n* 02 is used by dynamic catalog feature to fetch expected catalog to be brokered for client 0. Expected to be available at startup\n* 05 is typically used by paas-templates smoke tests. 05 would be emptied at each test execution. \n* 06 may be used by the embedded CF instance to consume brokered services\n\nOsb-cmdb provides smoke tests in the [paas-templates repo](https://github.com/orange-cloudfoundry/paas-templates/blob/manual-drop/ops-depls/cf-apps-deployments/osb-cmdb-broker/README.md) that uses CF as an OSB client to send OSB API calls to osb-cmdb.\n\nFollowing consumption of brokered services by smoke tests, Osb-cmdb have dynamically created spaces/service instances and service keys as described into [Functional overview](#functional-overview) \n\n```\n01    ├── osb-cmdb-backend-services-org-client-0 \n02    │   ├── default\n03    │   ├── cassandra\n04    │   └── mysql\n05    │       ├── mysql-service-instance-guid1\n06    │       └── mysql-service-key-guid1\n07    ├── osb-cmdb-brokered-services-org-client-0 \n08        ├── default \n09        └── smoke-tests\n10            ├── mysql-service-instance-1\n11            └── mysql-service-binding-1\n```\n\n* 03, 04 are dynamically created by osb-cmdb\n* 10 is a service instance request made with `cf create-service instance mysql-cmdb 10mb myinstance` by smoke tests\n    * 05 is the associated backend service in the cmdb\n* 11 is a service instance request made with `cf bind-service myapp myinstance` by smoke tests\n    * 06 is the associated service key in the cmdb\n\n#### Assigning roles and permissions\n\nThis section describes the use-cases and associated [cloudfoundry roles](https://docs.cloudfoundry.org/concepts/roles.html#roles) that each actor should be granted\n\nActor  | Use case  | Permission  | Details\n-- | -- | -- | --\ncmdb-operator | deploy cmdb | space developer on the cmdb broker space | --\ncmdb-operator | run smoke tests | space developer on the smoke test space | --\ncmdb-operator | inspect whole cmdb content | Global auditor | --\ncmdb-operator | troubleshoot/fix cmdb content | space developer on each cmdb space or cloud_controller.admin | --\nosb platform consummers | inspect cmdb content for their tenant | space auditor on each cmdb space of their tenant \u003c/br\u003ealternatively global editor | --\nosb service provider | inspect cmdb content for their service | space auditor on each cmdb space of their service offerings \u003c/br\u003ealternatively global editor | --\nosb service provider | register/update their brokers/service plans | cloud-controller.admin or delegated permission through 3rd party tooling (*) | --\nosb service provider | manage service plan visibility | cloud-controller.admin or delegated permission through 3rd party tooling (*) | --\n\n(*) See related pending work at https://github.com/orange-cloudfoundry/paas-templates/issues/792 \n\nTo assign global auditor role, refer to [uaa-user-management.html#global-auditor doc](https://docs.cloudfoundry.org/uaa/uaa-user-management.html#global-auditor)\n\n```\n$ uaac group add cloud_controller.global_auditor\n[...]\n$ uaac member add cloud_controller.global_auditor a-osb-platform-user-name\n \n```\n\n\n#### Metadata attached to backing services\n\nIn order to provide traceability from backing services to brokered services, the backing service instances are attached the following metadata:\n\nLabel name | Label value | Query usage | Read usage\n-- | -- | -- | --\nbacking_service_instance_guid | backing-service-instance-guid | used internally by osb-cmdb as a workaround for lack of support for service instance read endpoint, in order to get service instance params |  | \nbrokered_service_instance_guid | brokered-service-guid | find a backend service by brokered-service-guid in all orgs/spaces | (redundant with backend service instance name)  | \nbrokered_service_context_organization_guid | brokered-service-meta-org-guid | find all backing services for a brokered_service_context_organization_guid | lookup org guid for a given backing service | \nbrokered_service_context_space_guid | brokered-service-meta-space-guid | find all backing services for a brokered-service-space-guid | lookup space guid for a given backing service | \nbrokered_service_originating_identity_user_id | brokered-service [X-Broker-API-Originating-Identity](https://github.com/openservicebrokerapi/servicebroker/blob/master/profile.md#originating-identity-header) | find all backing services for a brokered-service-user-guid | lookup user guid for a given backing service | \n\nAnnotation name | Annotation value | ~~Query usage~~ (*) | Read usage\n-- | -- | -- | --\nbrokered_service_context_organization_name |  | N/A | lookup org name for a given backing service | \nbrokered_service_context_space_name |  | N/A |  lookup space name for a given backing service| \nbrokered_service_context_instance_name | | N/A | lookup service instance name for a given backing service | \nbrokered_service_api_info_location | [X-Api-Info-Location header](https://docs.cloudfoundry.org/services/supporting-multiple-cf-instances.html#x-api-info-location) | N/A | enforce dashboards authN and authZ | \n\n(*) annotations can not be queried in CF\n\nTo lookup metadata attached to a backing service instance, scripts is available at https://github.com/orange-cloudfoundry/cf-cli-cmdb-scripts to workaround incomplete CF V3 API and CF V7 CLI\n\n##### Metadata for CF OSB client \n\n```bash\n# Example of a backing service being looked up (corresponding to a brokered service instance provisionned by a CF OSB client)\n$ cf s\nGetting services in org osb-cmdb-backend-services-org-client-0 / space p-mysql as xx...\n\nname                                           service   plan   bound apps   last operation     broker    upgrade available\n3aa96c94-1d01-4389-ab4f-260d99257215   p-mysql   10mb                create succeeded   p-mysql \n\n$ cf_labels_service 80134f9b-b6fd-48e2-8ca5-e185c4cb5ce0\n{\n    \"labels\": {\n        \"brokered_service_instance_guid\": \"3aa96c94-1d01-4389-ab4f-260d99257215\",\n        \"brokered_service_context_organization_guid\": \"c2169b61-9360-4d67-968c-575f3a10edf5\",\n        \"brokered_service_originating_identity_user_id\": \"0d02117b-aa21-43e2-b35e-8ad6f8223519\",\n        \"brokered_service_context_space_guid\": \"1a603476-a3a1-4c32-8021-d2a7b9b7c6b4\",\n        \"backing_service_instance_guid\": \"191260bb-3477-422d-8f40-bf053ccf6930\"\n    },\n    \"annotations\": {\n        \"brokered_service_context_instance_name\": \"osb-cmdb-broker-0-smoketest-1578565892\",\n        \"brokered_service_context_space_name\": \"smoke-tests\",\n        \"brokered_service_api_info_location\": \"api.mycf.org/v2/info\",\n        \"brokered_service_context_organization_name\": \"osb-cmdb-brokered-services-org-client-0\"\n    }\n}\n```\n\n##### Metadata for K8S OSB client \n\n\n```\n# Example of a backing service being looked up (corresponding to a brokered service instance provisionned by a K8S OSB client)\n$ cf s\nGetting services in org osb-cmdb-backend-services-org-client-0 / space p-mysql as xx...\n\nname                                           service   plan   bound apps   last operation     broker    upgrade available\nb6a7a748-6fa5-497c-b111-a3a727ec88db           p-mysql   10mb                create succeeded   p-mysql  \n\n$ cf_labels_service b6a7a748-6fa5-497c-b111-a3a727ec88db\nMetadata for service b6a7a748-6fa5-497c-b111-a3a727ec88db:\n{\n  \"labels\": {\n    \"brokered_service_instance_guid\": \"b6a7a748-6fa5-497c-b111-a3a727ec88db\",\n    \"brokered_service_originating_identity_uid\": \"\",\n    \"brokered_service_context_namespace\": \"cloudfoundry-service-instances\",\n    \"backing_service_instance_guid\": \"6ea3cf73-cbb6-46be-b9c5-dbcf7b04064f\"\n  },\n  \"annotations\": {\n    \"brokered_service_originating_identity_extra\": \"{\\\"scopes.authorization.openshift.io\\\":[\\\"user:full\\\"]}\",\n    \"brokered_service_originating_identity_username\": \"a-user-name\",\n    \"brokered_service_originating_identity_groups\": \"[\\\"system:authenticated:oauth\\\",\\\"system:authenticated\\\"]\"\n  }\n}\n```\n\nThe svcat in OpenShift v3.9.51 ( Kubernetes v1.9.1+a0ce1bc657 ), does not provide its internal id (`wbv8r`  in the example below) in its OSB calls.  Correlation from svcat requires looking up the OSB service instance guid, named `ExternalId` into svcat cli\n\n```\n$ svcat get instances \n         NAME                     NAMESPACE                  CLASS           PLAN       STATUS  \n+---------------------+--------------------------------+---------------+--------------+--------+\n  noop-ondemand-jkpn4   cloudfoundry-service-instances   noop-ondemand   mysql-sample   Ready   \n  p-mysql-wbv8r         cloudfoundry-service-instances   p-mysql         10mb           Ready  \n  \n$ svcat describe instance p-mysql-wbv8r -v 9 2\u003e\u00261 | grep \"Response Body\" | sed 's/.*Response Body: //' | grep ServiceInstance | jq .spec.externalID\n\"b6a7a748-6fa5-497c-b111-a3a727ec88db\"  \n\n#Lookup in the cmdb a K8S provisionned instance from its externalID\n\n$ cf curl \"/v3/service_instances?label_selector=brokered_service_instance_guid==b6a7a748-6fa5-497c-b111-a3a727ec88db\" | jq .resources[]\n{\n  \"guid\": \"6ea3cf73-cbb6-46be-b9c5-dbcf7b04064f\",\n  \"created_at\": \"2020-02-27T17:35:43Z\",\n  \"updated_at\": \"2020-02-27T17:35:43Z\",\n  \"name\": \"b6a7a748-6fa5-497c-b111-a3a727ec88db\",\n  \"relationships\": {\n    \"space\": {\n      \"data\": {\n        \"guid\": \"38de12e4-3fc8-4698-a8b0-87e7a3dbf2ed\"\n      }\n    }\n  },\n  \"metadata\": {\n    \"labels\": {\n      \"brokered_service_instance_guid\": \"b6a7a748-6fa5-497c-b111-a3a727ec88db\",\n      \"brokered_service_originating_identity_uid\": \"\",\n      \"brokered_service_context_namespace\": \"cloudfoundry-service-instances\",\n      \"backing_service_instance_guid\": \"6ea3cf73-cbb6-46be-b9c5-dbcf7b04064f\"\n    },\n    \"annotations\": {\n      \"brokered_service_originating_identity_extra\": \"{\\\"scopes.authorization.openshift.io\\\":[\\\"user:full\\\"]}\",\n      \"brokered_service_originating_identity_username\": \"a-user-name\",\n      \"brokered_service_originating_identity_groups\": \"[\\\"system:authenticated:oauth\\\",\\\"system:authenticated\\\"]\"\n    }\n  },\n  \"links\": {\n    \"space\": {\n      \"href\": \"https://api.redacted.com/v3/spaces/38de12e4-3fc8-4698-a8b0-87e7a3dbf2ed\"\n    }\n  }\n}\n\n```\n\n#### Refreshing OSB client cache through Maintenance-info  \n\nOSB clients maintain a cache of the brokered service instance data returned from the OSB provisionning endpoint. In particular, this includes the dashboard url. \n\nWhenever the backing service dashboard url changes and needs to be reflected to brokered service instance fetched by OSB clients, OSB clients can request for a [service instance upgrade](https://docs.cloudfoundry.org/devguide/services/managing-services.html#upgrade).\n\nAdditionally, the 0.x version of osb-cmdb used to not propagate backing service instance dashboard to brokered services. Starting with 1.1.0 version, osb-cmdb can be opted-in to bump the [maintenance_info](https://github.com/openservicebrokerapi/servicebroker/blob/master/spec.md#maintenance-info-object) object within the served catalog, which enables users to upgrade brokered services without backing services supporting upgrades. The following configuration properties control the maintenance-info behavior:\n\nproperty name | default value | example value | description   \n-- | -- | -- \nosbcmdb.maintenanceinfo.version     | null| 1.1.0 | set as version if backing service has no maintenance_info.version, merged through addition otherwise \nosbcmdb.maintenanceinfo.description | null| osb-cmdb now propagates dashboard url | set as description if backing service has no maintenance_info.description, merged through string concat with LF otherwise \n \n\n### Technical details\n\n#### osb-cmdb osb client calls requirements\n\nThe OSB API specifications available at https://github.com/openservicebrokerapi/servicebroker/blob/master/spec.md are versatile and support multiple extensions. See https://github.com/openservicebrokerapi/servicebroker/blob/master/diagram.md for a visual overview.\n\nThis section lists the requirements that osb clients need to comply with in order to consumme services exposed by osb-cmdb.\n\n- The osb-cmdb expects OSB API calls matching OSB specification version 2.14 (this version will be updated in the future)\n- The cloudfoundry profile described at https://github.com/openservicebrokerapi/servicebroker/blob/master/profile.md MUST be used with the possible following relaxations\n   - The following fields are mandatory but may have fake, non empty values e.g. \"na\"\n       - organization_guid\n       - organization_name\n       - space_guid\n       - space_name\n       - instance_name\n- The client MUST support asynchronous service instance provisionning (see https://github.com/openservicebrokerapi/servicebroker/blob/master/spec.md#asynchronous-operations), i.e. provide the query parameter accepts_incomplete=true\n   - Service binding MAY only support blocking operation and specify the query parameter accepts_incomplete=false\n\n##### Future support for additional meta-data\n\nOnce OSB 2.16 version gets released and supported by osb-cmdb, the following additional fields MAY be used by clients to fill in arbitrary meta-data associated with service instances, see https://github.com/openservicebrokerapi/servicebroker/pull/658 for background:\n- instance_annotations\n- space_annotations\n- organization_annotations\n\nThese annotations get propagated into service monitoring/alerts.\n\n#### OSB-api extension (x-osb-cmdb) used with backing service brokers   \n\nBy default, when propagating OSB calls to backing service brokers, osb-cmdb adds an extra `x-osb-cmdb` param to the [service instance provisionning call](https://github.com/openservicebrokerapi/servicebroker/blob/master/spec.md#provisioning) containing additional metadata matching the [inventory metadata](#metadata-attached-to-backing-services) and an additional `brokered_service_client_name` property identifying the calling osb client, whose value matches the name of the backing service instance organization name. This can be opted-out with the `osbcmdb.broker.propagateMetadataAsCustomParam=false` flag\n\nNote that by default, this `x-osb-cmdb` param isn't returned by the [service instance fetch endpoint](https://github.com/openservicebrokerapi/servicebroker/blob/master/spec.md#fetching-a-service-instance). This can be opted-out with `osbcmdb.broker.hideMetadataCustomParamInGetServiceInstanceEndpoint=false` flag\n\n##### Example for CF profile\n\n```json\n{\n  \"x-osb-cmdb\": {\n    \"annotations\": {\n      \"brokered_service_context_spaceName\": \"smoke-tests\",\n      \"brokered_service_context_organizationName\": \"osb-cmdb-brokered-services-org-client-0\",\n      \"brokered_service_api_info_location\": \"api.redacted-domain.com/v2/info\",\n      \"brokered_service_context_instanceName\": \"osb-cmdb-broker-0-smoketest-1600699922\",\n      \"brokered_service_client_name\": \"osb-cmdb-backend-services-org-client-1\",\n      \"brokered_service_context_organization_annotations\": \"{\\\"domain.com/org-key1\\\":\\\"org-value1\\\",\\\"orange.com/overrideable-key\\\":\\\"org-value2\\\"}\",\n      \"brokered_service_context_space_annotations\": \"{\\\"domain.com/space-key1\\\":\\\"space-value1\\\",\\\"domain.com/space-key2\\\":\\\"space-value2\\\"}\",\n      \"brokered_service_context_instance_annotations\": \"{\\\"domain.com/instance-key1\\\":\\\"instance-value1\\\",\\\"orange.com/overrideable-key\\\":\\\"instance-value2\\\"}\"\n    },\n    \"labels\": {\n      \"brokered_service_instance_guid\": \"7d9235c5-242d-4b17-ac82-935f121ffd7f\",\n      \"brokered_service_context_organization_guid\": \"c2169b61-9360-4d67-968c-575f3a10edf5\",\n      \"brokered_service_originating_identity_user_id\": \"0d02117b-aa21-43e2-b35e-8ad6f8223519\",\n      \"brokered_service_context_space_guid\": \"1a603476-a3a1-4c32-8021-d2a7b9b7c6b4\",\n      \"brokered_service_context_orange_overrideable-key\": \"instance-value2\"\n    }\n  }\n}\n```\n\nNote that the CloudFoundry annotations with prefix \"orange.com/\" are automatically merged in precedence order (org/space/instance) into a key with the \"orange.com/\" prefix trimmed (`brokered_service_context_orange_overrideable-key` in the example below)\n\n##### Example for K8S profile\n\n```json\n{\n  \"annotations\": {\n    \"brokered_service_originating_identity_extra\": \"{\\\"scopes.authorization.openshift.io\\\":[\\\"user:full\\\"]}\",\n    \"brokered_service_originating_identity_username\": \"a-user-name\",\n    \"brokered_service_originating_identity_groups\": \"[\\\"system:authenticated:oauth\\\",\\\"system:authenticated\\\"]\",\n    \"brokered_service_client_name\": \"osb-cmdb-backend-services-org-client-1\"\n  },\n  \"labels\": {\n    \"brokered_service_instance_guid\": \"b6a7a748-6fa5-497c-b111-a3a727ec88db\",\n    \"brokered_service_originating_identity_uid\": \"\",\n    \"brokered_service_context_namespace\": \"cloudfoundry-service-instances\"\n  }\n}\n```\n\n\n\n\n\n#### Dashboard AuthN and AuthZ support (WIP)\n\nUIs/Dashboard presented to developers (e.g. quotas and in the future backup/restore and monitoring) use OpenIdConnect (https://openid.net/specs/openid-connect-core-1_0.html) for user authentication (AuthN) and a REST endpoint for authorization (AuthZ). This is inspired from https://docs.cloudfoundry.org/services/dashboard-sso.html\n\n##### Discovery of the OIDC endpoint\n\nThis section below detail how osb-cmdb discovers the OIDC and AuthZ from Osb API calls:\n\nOsb-cmdb expects to receive the X-Api-Info-Location header in all OSB API calls. This header documented at https://docs.cloudfoundry.org/services/supporting-multiple-cf-instances.html (until this header makes it into the OSB API, see cf https://github.com/openservicebrokerapi/servicebroker/pull/686 )\n \nThe X-Api-Info-Location header MUST return a Url (similar to https://api.cloudfoundry.redacted-domain.org/v2/info ) whose response should have header « Content-Type: application/json;charset=utf-8 » and a body at least containing the following field keys, (and appropriate values).\n \n{  \"authorization_endpoint\": \"https://login.redacted-domain.org\",\n  \"token_endpoint\": \"https://uaa.redacted-domain.org\",\n}\n\nThese 2 fields provide access to OIDC authorization and token endpoints.\n\n##### Discovery of the OAuth client_id and client_secret to provision\n\nThe clients are expected to comply with the Cloudfoundry catalogue extension documented at https://github.com/openservicebrokerapi/servicebroker/blob/master/profile.md#cloud-foundry-catalog-extensions with an extract reproduced below.\n\n{\n  \"services\": [{\n    \"name\": \"fake-service\",\n    \"id\": \"acb56d7c-XXXX-XXXX-XXXX-feb140a59a66\",\n    \"description\": \"A fake service.\",\n    \"dashboard_client\": {\n      \"id\": \"398e2f8e-XXXX-XXXX-XXXX-19a71ecbcf64\",\n      \"secret\": \"277cabb0-XXXX-XXXX-XXXX-7822c0a90e5d\",\n      \"redirect_uri\": \"http://localhost:1234\"\n    }\n  }]\n}\n\nClients are expected to provision an OAuth2 client matching the id/secret and restrict http redirections to the specified redirect_uri.\n\n##### Dashboard AuthN using OIDC\n\nThe OSB-CMDB directs users into an Oauth2 authorization grant flow (see https://tools.ietf.org/html/rfc6749#section-4.1 and CF UAA implementation at https://docs.cloudfoundry.org/api/uaa/version/74.4.0/index.html#authorization-code-grant ) with the following authorize endpoint parameters\n\n    response_type= code\n    client_id: the oauth client claimed in the catalog cloudfoundry extension described above.\n    redirect_uri\n    scope=cloud_controller_service_permissions.read openid\n    state\n    nonce\n\n\nThis authorization grant flow grants the OSB-CMDB with an access token which is then used for invoking the authorization REST endpoint.\n\nThis authorization grant flow may also provide the OSB-CMDB with an OIDC id token, used to fetch developer identity (in Id token standard claims https://openid.net/specs/openid-connect-core-1_0.html#StandardClaims or UserInfo endpoint https://openid.net/specs/openid-connect-core-1_0.html#UserInfo ). This may be used in the future in audit events.\n\n\nBelow is an extract from the OAuth2 specifications describing the authorization grant flow interactions\n\n     +----------+\n     | Resource |\n     |   Owner  |\n     |          |\n     +----------+\n          ^\n          |\n         (B)\n     +----|-----+          Client Identifier      +---------------+\n     |         -+----(A)-- \u0026 Redirection URI ----\u003e|               |\n     |  User-   |                                 | Authorization |\n     |  Agent  -+----(B)-- User authenticates ---\u003e|     Server    |\n     |          |                                 |               |\n     |         -+----(C)-- Authorization Code ---\u003c|               |\n     +-|----|---+                                 +---------------+\n       |    |                                         ^      v\n      (A)  (C)                                        |      |\n       |    |                                         |      |\n       ^    v                                         |      |\n     +---------+                                      |      |\n     |         |\u003e---(D)-- Authorization Code ---------'      |\n     |  Client |          \u0026 Redirection URI                  |\n     |         |                                             |\n     |         |\u003c---(E)----- Access Token -------------------'\n     +---------+       (w/ Optional Refresh Token)\n\n       Note: The lines illustrating steps (A), (B), and (C) are broken into\n       two parts as they pass through the user-agent.\n\n                     Figure 3: Authorization Code Flow\n\n       The flow illustrated in Figure 3 includes the following steps:\n    \n       (A)  The client initiates the flow by directing the resource owner's\n            user-agent to the authorization endpoint.  The client includes\n            its client identifier, requested scope, local state, and a\n            redirection URI to which the authorization server will send the\n            user-agent back once access is granted (or denied).\n    \n       (B)  The authorization server authenticates the resource owner (via\n            the user-agent) and establishes whether the resource owner\n            grants or denies the client's access request.\n    \n       (C)  Assuming the resource owner grants access, the authorization\n            server redirects the user-agent back to the client using the\n            redirection URI provided earlier (in the request or during\n            client registration).  The redirection URI includes an\n            authorization code and any local state provided by the client\n            earlier.\n    \n       (D)  The client requests an access token from the authorization\n            server's token endpoint by including the authorization code\n            received in the previous step.  When making the request, the\n            client authenticates with the authorization server.  The client\n            includes the redirection URI used to obtain the authorization\n            code for verification.\n    \n       (E)  The authorization server authenticates the client, validates the\n            authorization code, and ensures that the redirection URI\n            received matches the URI used to redirect the client in\n            step (C).  If valid, the authorization server responds back with\n            an access token and, optionally, a refresh token.\n\n\n##### Dashboard AuthZ using CF service instance permission\n\nA distinct AuthZ endpoint GET /v2/service_instances/:guid/permissions (matching https://apidocs.cloudfoundry.org/12.1.0/service_instances/retrieving_permissions_on_a_service_instance.html ) MUST be supported and available at the same FQDN than the Url retourned by the X-Api-Info-Location header.\n\nThis endpoint will receive a JWT OAuth2 bearer access token provided by developers browser in its web session when accessing the dashboard (see section above)\n \nThe osb-cmdb will authenticate users accessing dashboards using OIDC and the AuthZ endpoint.\nThe user AuthZ will be performed according to the AuthZ endpoint response which MUST respond with the following JSON formatted response\n \n{\n  \"manage\": true,\n  \"read\": true\n}\n##### Dashboard AuthZ using K8S API\n\nWhen a K8S OSB client (such as service catalog) requires authorization of K8S users, the osb-cmdb plans to leverage the K8S SubjectAccessReview endpoint https://kubernetes.io/docs/reference/kubernetes-api/authorization-resources/subject-access-review-v1/ for checking the permissions of SVCat resource associated wth the OSB provisionned service instance\n\nFrom https://kubernetes.io/docs/reference/access-authn-authz/authorization/#checking-api-access\n\u003e SelfSubjectAccessReview is part of the authorization.k8s.io API group, which exposes the API server authorization to external services. Other resources in this group include:\n\u003e SubjectAccessReview - Access review for any user, not only the current one. Useful for delegating authorization decisions to the API server.\n\n\n##### Interaction flow diagram\n\nThe following diagram summarizes the interactions between OSB-CMDB and its clients (inspired by https://gist.github.com/hrchu/d88efb56e72534a1233d16f36eb3e3e9)\n\n![sequence diagram](./osb-cmdb/seq-diagram.png)\n\n### Contributing\n\n#### Credits\n\nThis project initially spiked and inspired from the great [spring-cloud/spring-cloud-app-broker](https://github.com/spring-cloud/spring-cloud-app-broker) project. After attempting upstream contribution in `spring-cloud-app-broker` to support osb-cmdb use-cases, see [#6](https://github.com/orange-cloudfoundry/osb-cmdb-spike/issues/6) and related issue [spring-cloud/spring-cloud-app-broker/#285](https://github.com/spring-cloud/spring-cloud-app-broker/issues/285), a redesign and reimplementation of osb-cmdb independently of `spring-cloud-app-broker` was conducted in version 1.0, see [#13](https://github.com/orange-cloudfoundry/osb-cmdb-spike/issues/13). Osb-cmdb 1.0 still uses some app-broker configuration (prefixed with `spring.cloud.appbroker.`, acceptance and component-test code fragments, referenced with acronym SCAB below. \n\n#### Design documentation\n\nDesign docs, and implementation notes are available in the [osb-cmdb/docs/impl-notes](osb-cmdb/docs/impl-notes) directory\n\n#### Circle ci tests\n\nCircle ci tests run offline without a cloudfoundry instance. They include scab tests and osb-cmdb tests. See osb-cmdb/.circle/config.yml\n\n#### Acceptance tests\n\nAcceptance tests run privately against a live cloudfoundry instance. Tests are private because it is hard to secure logs to not leak credentials that could be used to abuse the Cloud Foundry instance.\n\nSee https://github.com/orange-cloudfoundry/osb-cmdb-ci for the concourse task running the acceptance tests.\n\nLike scab, osb-cmdb acceptance tests use distinct properties than osb-cmdb production properties. Refer to [Getting started](#getting-started) for the list of prod properties supported, and paas-templates smoke tests. \n\nSee more details in [spring-cloud-app-broker-acceptance-tests/README.adoc](spring-cloud-app-broker-acceptance-tests/README.adoc)\n\n#### Releasing\n\n* manually edit the version in `gradle.properties` (e.g `version=1.1.0`), commit \u0026 push\n* git tag v1.1.0 -a -m \"1.1.0 release\"\n* git push origin  v1.1.0\n* let circle ci build and upload the binaries to github\n* edit the github release to complete release notes\n* manually edit the version in `osb-cmdb/gradle.properties`, commit \u0026 push e.g. `version=0.2.0.BUILD-SNAPSHOT`\n* [ ] fix unit tests invocation currently expecting version in jar name (e.g. `osbcmdb-1.0.0.jar`) \n   * [ ] fix osb-cmdb-ci  \n   * [ ] fix intellij run configurations  \n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Forange-cloudfoundry%2Fosb-cmdb","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Forange-cloudfoundry%2Fosb-cmdb","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Forange-cloudfoundry%2Fosb-cmdb/lists"}