The following is a discussion of potential features and design improvements that can improve developer's user experience in deploying Conjur-enabled applications using the [Conjur Kubernetes Sidecar].
The agenda for this discussion:
- Pain Points in the Current Workflow
- Proposed Features to be Added
- Option: Conjur Policy Generator for App Integration
- Option: Conjur App Authentication Operator
- List of Task/User Stories
Our best documentation for developers to follow when integrating their Kubernetes applications with Conjur are in the Kubernetes Conjur Demo repo, Kubernetes-in-Docker example in the Conjur OSS Helm chart repo, and the Conjur Sidecar Injector repo.
Some reflections on this documentation:
- Our documentated workflow uses a collection of
bash
scripts The scripts use environment variables, and usesed
for manifest templating (one exception is that there is a Helm chart to deploy the sidecar injector). It would be more Kubernetes-native and streamlined to use Helm charts with defaults/settings invalues.yaml
files. - The bash scripts mix security admin vs. application deployment concerns: Security-admin-related tasks that are common to every Application/Conjur integration are not broken out separately from the business of deploying the actual application. It would be better to provide a separate Helm chart for deploying the Conjur-related or security-admin related resources. Such a Helm chart could be used by a privileged security admin before the application is deployed.
- Without the sidecar injector, app integration requires adding many lines to an app deployment manifest to add a sidecar.
- Generating Conjur policy is complicated
- Loading Conjur policy can be more automated, Kubernetes-native, and more streamlined.
(Note: One benefit to creating Helm charts for the various deployments is that the Helm charts can eventually be incorporated into a Helm operator that is generated via Operator SDK.)
It would help to provide a new Helm chart that takes care of deploying the Conjur-related or security-admin related Kubernetes resources that are common to every application/Conjur integration.
This application authentication Helm chart could be used by a privileged security admin (separate from application deployment) to perform the following:
- Create a Conjur CA certificate ConfigMap in the application namespace
- Create a RoleBinding in application namespace to allow Conjur authenticator to access resources in this namespace.
- Create a Conjur policy loader Kubernetes
Job
to load security policy into Conjur. ThisJob
can be activated via:- Helm post-install hook
- Helm post-upgrade hook
This
Pod
created for thisJob
can be based on the Conjur CLI container image. Alternatively, thisJob
can be based upon a container that incorporates the Conjur Golang API to load the policy into Conjur.
- Create Kubernetes Secret (or ConfigMap) to pass the Conjur policy definitions. Helm can read policy files on the Helm host and add the file content to a Kubernetes Secret. The Conjur policy loader Job would then be able to read the policy content (which would be volume mounted to its file system) and load that policy in Conjur.
It would be helpful for developers to have a sample/demo application Helm chart that uses the sidecar injector. This can be largely based on the application manifests in the Kubernetes Conjur Demo repo. This might be implemented first as a separate Helm chart repository, but we could ultimately consider converting the existing cyberark/kubernetes-conjur-demo repo to use the Sidecar injector integrations that we're developing.
i.e. Find a better way to generate Conjur authentication policy files for an application.
Currently, the Conjur policy manifests for application authentication is done via
bash scripts, using sed
for templating.
A big question is whether the Conjur policy that is generated is fairly standard/common across applications, and can be considered to be mostly made up of boilerplate YAML. If this is true, then it may be possible to create a authentication policy generator that takes a "boiled-down", or minimized policy configuration for a particular application, and generates policy files from that (minimal) data. The minimized policy configuration might look something like the following (NOTE: This is just very rough guess at what the required policy config is):
policy:
authenticatorID: my-authenticator-id
appIdentityPolicy:
id: test-app
owner: devops
description: This policy connects authn identities to an application identity. It defines a layer named for an application that contains the whitelisted identities that can authenticate to the authn-k8s endpoint. Any permissions granted to the application layer will be inherited by the whitelisted authn identities, thereby granting access to the authenticated identity.
members:
- apps
endpointPolicy:
owner: cluster_admin
description: This policy defines an authn-k8s endpoint, CA creds and a layer for identities that are permitted to authenticate to it.
layer: users
role: users
members:
- apps
appPolicy:
id: apps
owner: devops
description: Identities permitted to authenticate
hosts:
- id: test-app-secretless
annotations:
- id: authn-k8s/namespace
value: {{ .Release.Namespace }}
- id: authn-k8s/service_account
value: test-app-secretless
- id: authn-k8s/deployment
value: test-app-secretless
- id: authn-k8s/authentication-container-name
value: secretless
- id: kubernetes
value: true
IF it is possible to derive a minimalized configuration that can work for most applications, then the following methods might be worth considering:
- Use Helm. The authentication policies can be templated in a Helm chart
e.g. as part of the
data
field of a Kubernetes secret manifest that will get consumed by a Conjur policy loader Job. - Create a Golang program to read the minimalized configuration and generate the authentication policies. This could either be run before running the application authentication Helm chart, or incorporated into an application authentication operator.
- Incorporate either of the 2 bullets above into a application authentication Helm operator, so that the application developer would set the configuration shown above as part of a Custom Resource instantiation.
Even if we devised such a policy generator, we would probably still need to support using full Conjur policy manifests directly, in order to handle application scenarios that use Conjur policies that don't exactly conform to what is being generated here.
Instead of requiring a security admin to use the Conjur application authentication Helm chart (as described above), it would be an even better user experience if an operator is available to execute all of the security-admin tasks related to application authentication. This would allow the application developer to simply create a Custom Resource instance of an application-authn CRD to trigger the loading of Conjur policy and creation of a RoleBinding, etc.
It may be possible to generate an operator from the application authentication Helm chart described above using Operator SDK. (Alternatively, a custom Golang operator can be created using KubeBuilder or Operator SDK, but that probably take bit more development work).
- Create a Helm chart for Conjur application authentication resources, includeing:
- Conjur CA certificate ConfigMap
- RoleBinding for Conjur authn
- Job for loading Conjur policy
- Secret for passing Conjur policy files
- Create a Helm chart for a demo application Helm chart that uses the Sidecar injector and the Conjur application authentication Helm chart (e.g. as a sub-chart) to do security admin tasks (or convert the existing cyberark/kubernetes-conjur-demo to use the sidecar injector, and uses a Helm chart instead of bash/sed to deploy the app).
- Incorporate sidecar injector Helm chart into Conjur OSS helm chart
- Timebox: Determine if there is a common, minimalized config that can be used for generating Conjur authentication policy
- Optional: Create a Helm operator from the Conjur application authentication Helm chart
- Optional: Streamline policy generation (depending upon timeboxed investigation above) using Helm templating or a Golang program.
- E2E testing based on all of the above
- Documentation