Declarative Configuration Import for Cloudentity
Cloudentity declarative configuration feature enables deployment agents to import and declaratively Cloudentity. Learn how to utilize the Cloudentity Helm Chart to speed up your workflow and declaratively configure your Cloudentity deployment.
About Configuration Import
In addition to Cloudentity's import APIs, it is possible to configure your Cloudentity deployment declaratively using the acp-cd Helm Chart. The configuration import can be used for all Cloudentity deployment types including the Cloudentity SaaS deployment or Cloudentity deployment on Kubernetes.
The acp-cd Helm Chart is responsible for creating a Kubernetes job that seeds Cloudentity with configuration. You can, for example, define client applications, gateways (both for multi-tenant and single-tenant authorizers), policies, and APIs.
Note
For a detailed list of entities that you can configure and for references, see:
Declarative configuration import allows you to use the GitOps approach. You can store configuration inside your Git repository and have your configuration and infrastructure as code. In this case, your Git repository acts as a single source of truth for your Cloudentity configuration. This leads to increased productivity for your teams, enhanced developer experience, improved stability and reliability, consistency, and many more.
Using declarative configuration import it is much easier to integrate with DevSecOps pipelines. You can execute the import job in a satellite environment that communicates with Cloudentity using the import API protected by the System tenant credentials.
Prerequisites
Access to the Cloudentity tenant and its System workspace.
Tip
The
importJob
results in a call to Cloudentity's import configuration API that is protected by System workspace credentials. System workspace access, by default, is hidden behind a feature flag. If you need access to the System workspace for your tenant, contact Cloudentity Sales team.Client application created in the System workspace.
Note
To be able to import the defined configuration, your import job needs to be able to authenticate to Cloudentity by calling the Cloudentity OAuth 2.0 token endpoint . Therefore, you need to allow the client credentials OAuth grant flow for your client application and assign the
manage_configuration
scope to it. To learn more about creating clients used for calling Cloudentity's APIs, see Getting Started with Cloudentity REST APIs.Kubernetes cluster up and running.
For the purpose of this article, the acp-on-k8s environment is used that allows you to rapidly stand up your Cloudentity instance in your local development environment. For prerequisites and references for this deployment, visit a dedicated acp-on-k8s GitHub repository.
Helm version 3.0 or subsequent.
Install acp-cd Helm Chart
In your terminal, execute the following commands to get your Helm repository updated:
helm repo add acp https://charts.cloudentity.io helm repo update
Install your Helm Chart using the
helm -n [NAMESPACE] install [RELEASE-NAME] [CHART] -f [VALUES.YAML FILE]
command:helm -n [NAMESPACE] install [RELEASE-NAME] [CHART] -f [VALUES.YAML FILE] \ --set clientCredentials.clientID={YOUR_IMPORT_JOB_CLIENT_IDENTIFIER} \ --set clientCredentials.clientSecret={YOUR_IMPORT_JOB_CLIENT_SECRET} \ --set clientCredentials.issuerURL={YOUR_ISSUER_URL} \
Example:
helm -n acp-system install sample-acp-cd-release acp/acp-cd -f values/acp-cd.yaml \ --set clientCredentials.clientID=sample-import-client \ --set clientCredentials.clientSecret=_D0Nze6aocqxW7hafyeJZarF-NQZi9FGDd2SIZgANhA \ --set clientCredentials.issuerURL=https://example.com \
Using the above command you install your
acp-cd
Helm Chart in theacp-system
Kubernetes namespace as a part of thesample-acp-cd-release
. To provide values for your chart, you use theacp-cd.yaml
file.--set
arguments are used to provide values for the client credentials of your import job client.Tip
Optionally, you can install your Helm Chart with the values for client credentials set in your custom
values.yaml
file.Helm resolves values in the following order:
Values set using the
--set
argumentValues from the custom
values.yaml
fileValues from the default
values.yaml
file.
Client Credentials and Security
Be cautious while using client credentials of your import client. It is a client created in the System tenant, therefore, it can be used to access Cloudentity's System APIs. For testing purposes, you can use
--set
arguments or provide values in thevalues.yaml
file.Production environments should have Kubernetes secrets created manually with the
clientCredentials.create
value set tofalse
in yourvalues.yaml
file.To increase security of secrets stored in your repository, it is recommended to encrypt your Kubernetes secrets. You can use tools like Mozilla SOPS or Bitnami Sealed Secrets to encrypt your secrets.
When the secrets are applied to your Kubernetes deployment, the secrets are encrypted and visible as plain text. Anyone who is authorized to create a Pod in a namespace can read any secret in that namespace; this includes indirect access such as the ability to create a Deployment. To mitigate the risks, kubernetes recommends to:
Enable encryption at Rest for secrets.
Enable or configure RBAC rules that restrict reading data in secrets.
Where appropriate, use mechanisms such as RBAC to limit which principals are allowed to create or replace secrets.
To learn more, visit Kubernetes secrets documentation
Configure root CAs for ACP-CD HTTP client
To provide the path to the root CAs to configure trusted certificates for acp-cd HTTP client, configure the following value in the
values.yaml
file:client: rootCA: "./ca.pem"
Configure acp-cd client
You can configure acp-cd client by providing your configuration as part of the config value in the
values.yaml
file.Example:
config: data: client: insecure_skip_verify: false # disable cert verification
Define Configuration Import
Below, you can find a couple of examples how to import configuration for objects, such as client applications, gateways, identity providers, and more. After you define your configuration import, upgrade your Helm Chart release.
Identity Sources
To import an IDP configuration, add your IDP definition to your values.yaml
file in the data
section. See example below:
data: idps: - id: c49qvgb0djbgslsgvp3g tenant_id: { tid } authorization_server_id: { aid } name: GitHub Sample IDP disabled: false method: github attributes: - name: user_data.login description: Login type: string labels: null - name: user_data.id description: ID type: number labels: null - name: user_data.site_admin description: Site admin type: bool labels: null - name: user_data.name description: Name type: string labels: null - name: user_data.company description: Company type: string labels: null - name: user_data.email description: Email type: string labels: null - name: groups description: Groups type: string_array labels: null mappings: - source: user_data.name target: name type: string allow_weak_decoding: false - source: user_data.email target: email type: string allow_weak_decoding: false - source: groups target: groups type: string_array allow_weak_decoding: false static_amr: [] transformer: enabled: false script: "" config: enable_stateful_ctx: false stateful_ctx_duration: 0s discovery_settings: domains: [] instant_redirect: false token_exchange_settings: enabled: false identity_pool_id: null
Client Applications
To import client applications, add your application definition to your values.yaml
file in the data
section. See example below:
data: clients: - tenant_id: {tid} authorization_server_id: configuration-import client_id: acme-client client_secret: {sample-client-secret} token_endpoint_auth_method: client_secret_post system: false trusted: true client_name: Sample ACME client application application_type: web grant_types: - authorization_code response_types: - code - token - code scopes: - email - offline_access - openid
Note
For detailed reference of client application configuration, see Create new OAuth client API reference
Authorizers
In Cloudentity, an authorizer object consists in fact of two entities: an actual authorizer, and a client application created for this authorizer in the System workspace. When an authorizer makes requests to Cloudentity to, for example, fetch authorization policies, it uses client credentials of its client application to authenticate to Cloudentity. Therefore, if you import an authorizer, you must import a client application for this authorizer as well.
Warning
Your client application must be created within the System workspace for your tenant. For the client configuration, set the authorization_server_id
to system
.
The client application must have the following scopes assigned: introspect_tokens
, push_gateway_requests
, read_gateway_configuration
, write_gateway_configuration
.
To import an authorizer and its client application, add their definition to your values.yaml
file in the data
section. See example below:
data: gateways: - tenant_id: {tid} authorization_server_id: configuration-import id: sample-pyron-authorizer client_id: pyron-authorizer-client client_secret: cf53caab-fb55-40a7-8c63-620ce11102e2 name: Sample Pyron Authorizer description: Sample imported Pyron Authorizer type: pyron create_and_bind_services_automatically: true clients: - tenant_id: {tid} authorization_server_id: system client_id: pyron-authorizer-client client_secret: cf53caab-fb55-40a7-8c63-620ce11102e2 token_endpoint_auth_method: client_secret_basic system: false trusted: false client_name: Pyron Authorizer client application_type: web grant_types: - client_credentials response_types: - code scopes: - introspect_tokens - push_gateway_requests - read_gateway_configuration - write_gateway_configuration
Tip
You can create authorizers of any type. The type
parameter for your gateway object must be one of: apigeeedge
, apigeex
, aws
, azure
, istio
, kong
, pyron
, standalone
.
For a detailed reference regarding authorizers configuration, see Create gateway API reference
Authorization Policies
To import policies, add their definition to your values.yaml
file in the data
section. You can import both Cloudentity and REGO policies. See the examples below:
Cloudentity policies have
language
specified ascloudentity
and are defined byvalidators
:data: policies: - tenant_id: { tid } server_id: { aid } id: block_test_policy policy_name: block_test language: cloudentity type: api validators: - name: "false" - tenant_id: { tid } server_id: { aid } id: allow_test_policy policy_name: allow_test language: cloudentity type: api validators: - name: "true"
REGO policies have
language
specified asrego
and are defined in thedefinition
object containing REGO policy definition:data: policies: - tenant_id: { tid } server_id: { aid } id: auth_ctx_check_policy language: rego policy_name: check_email type: user definition: | package acp.authz default allow = false allow { input.authn_ctx.email == "test@gmail.com" } recovery = ["mfa"]
Note
For a detailed reference for authorization policies configuration, see Create policy API reference , Create Policy, and Create REGO Policy.
API Groups and Services
Note
To fully comply with the GitOps philosophy, you can disable service discovery for your authorizer. In this case, the authorizer does not discover any services within your deployment and only the services that you import are available within Cloudentity.
If you want your Cloudentity to be declaratively configured, Cloudentity recommends disabling the service discovery. This way, you have full control over your changes history and your configuration changes are transparent.
To import API groups and services add their definition to your values.yaml
file in the data
section. See example below:
data: gateway_api_groups: - tenant_id: {tid} server_id: {aid} service_id: httpbin_service gateway_id: sample-pyron-authorizer name: default/httpbin_api_group id: c5n8akdcqsna55j67220 apis: - method: GET path: /deny - method: GET path: /anything services: - id: httpbin_service tenant_id: {tid} authorization_server_id: {aid} gateway_id: sample-pyron-authorizer name: default/httpbin_service apis: - method: GET path: /deny can_have_policy: true policy_id: block_test_policy - method: GET path: /anything can_have_policy: true policy_id: allow_test_policy
What Should You Import
There are two scenarios according to which you should adjust your import:
Service discovery is disabled for your authorizer.
You should import both API groups and services definition.
Service discovery is enabled for your authorizer.
You should import only your services definition. API groups within your configured namespaces are discovered for your authorizer automatically.
Imported configuration from the above example contains:
httpbin API group for a sample Pyron Authorizer
In the import example above, you can see that the API group has the
c5n8akdcqsna55j67220
group identifier set. If we were to look at the Pyron Gateway, the API group identifier in the gateway would be the same. In your imported configuration, the API group identifiers must match API group identifiers from your gateway.403 NO RULE Status
When an authorizer is set up to protect APIs and a request is made to an API, the authorizer responds with the
403 NO RULE
status if:The service is not added to configuration.
The configuration contains an incorrect API group identifier for the group and the authorizer fails to match the request to the API group.
For testing purposes, this behavior can be adjusted by setting the
ENFORCEMENT_ALLOW_UKNOWN
parameter totrue
in your authorizer's configuration. It causes the authorizer to not return the403 NO RULE
status when matching is done incorrectly.httpbin service for a sample Pyron Authorizer
API Group and Service IDs for Istio Authorizer
For Istio Authorizer, API group identifiers or services identifiers are Base64 URL encoded SPIFFE IDs which are built being based on the service account of the protected pod. To avoid using long and unreadable API groups and service identifiers, Cloudentity supports Base64 encoding of SPIFFE IDs. To learn how to provide your API group or service identifier, see Istio Service Mesh.
Upgrade acp-cd Chart
To upgrade your acp-cd
Helm Chart values, execute the following command in your terminal:
helm -n [NAMESPACE] upgrade [RELEASE-NAME] [CHART] -f [VALUES.YAML FILE] \
Example:
helm -n acp-system upgrade sample-acp-cd-release acp/acp-cd -f values/acp-cd.yaml \
Your Helm Chart gets updated and the Kubernetes job uses Cloudentity import API to apply your configuration changes.