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.
Declarative Configuration Capabilities
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.
System Workspace Access
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.
Client Configuration
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 the Getting started with Cloudentity REST API -
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.Alternative Scenario
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
argument -
Values from the custom
values.yaml
file -
Values 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
Reference
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.
Remember
Your client application must be created within the System workspace for your tenant. For the client configuration, set the
authorization_server_id
tosystem
.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
Reference
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"]
Reference
For a detailed reference for authorization policies configuration, see Create policy API reference, Creating Cloudentity policies in the Visual Policy Editor, and Protecting Applications and APIs in Cloudentity Using Open Policy Agent.
API Groups and Services
Disabling Service Discovery
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 Declarative configuration import for Istio Authorizer article.
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.