diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..d58187f6 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,5 @@ +## Contributing + +The AAD Pod Identity project welcomes contributions and suggestions. Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your contribution. For details, visit https://cla.microsoft.com. + +When you submit a pull request, a CLA-bot will automatically determine whether you need to provide a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the instructions provided by the bot. You will only need to do this once across all repos using our CLA. diff --git a/README.md b/README.md index fb899531..923c61a5 100644 --- a/README.md +++ b/README.md @@ -1,221 +1,308 @@ ----- -Aad Pod Identity enables applications running in pods on Kubernetes clusters deployed on Azure(managed or unmanaged) to securely access cloud resources by leveraging Azure Active Directory(AAD). Administrators can configure identities and bindings, to match pods with identities. Following this, without any code modifications, the applications running within the pod can access any cloud resources that depend on AAD as Identity Provider. The administrator interactions with the aad-pod-identity are via Kubernetes primitives. - ----- +# AAD Pod Identity [![Build Status](https://dev.azure.com/azure/aad-pod-identity/_apis/build/status/aad-pod-identity-CI?branchName=master)](https://dev.azure.com/azure/aad-pod-identity/_build/latest?definitionId=22&branchName=master) +[![GoDoc](https://godoc.org/github.com/Azure/aad-pod-identity?status.svg)](https://godoc.org/github.com/Azure/aad-pod-identity) +[![Go Report Card](https://goreportcard.com/badge/github.com/Azure/aad-pod-identity)](https://goreportcard.com/report/github.com/Azure/aad-pod-identity) + +AAD Pod Identity enables Kubernetes applications to access cloud resources securely with [Azure Active Directory] (AAD). + +Using Kubernetes primitives, administrators configure identities and bindings to match pods. Then without any code modifications, your containerized applications can leverage any resource in the cloud that depends on AAD as an identity provider. + +---- + +## Contents -## Table of Contents -* [Design](#design) -* [Components](#components) * [Getting Started](#getting-started) -* [Demonstration](#demonstration) -* [Tutorial](#tutorial) -* [Debugging](#debugging) -* [Contributing](#contributing) - -## Design - -The detailed design of the project can be found in the following docs: -- [Concept](https://github.com/Azure/aad-pod-identity/blob/master/docs/design/concept.md) -- [Block Diagram](https://github.com/Azure/aad-pod-identity/blob/master/docs/design/concept.png) - -## Components - -### Managed Identity Controller(MIC) - -This controller watches for relevant changes to pods, identities, and bindings through the API server. When a change is detected it runs a loop to check if there are actions to be performed. Based on the change detected MIC would either add or delete assigned identities. In case of user assigned identity usage, MIC is responsible for assigning it to the underlying VM in which the pod gets scheduled during pod creation. During pod deletion it would remove those identities from the VM. Similar steps are taken by MIC when identities or bindings are created or deleted. - -### Node Managed Identity(NMI) - -The authorization request for fetching Service Principal Token from MSI endpoint is sent to a standard Instance Metadata endpoint which is redirected to the NMI pod by adding ruled to redirect POD CIDR traffic with metadata endpoint IP on port 80 to be sent to the NMI endpoint. The NMI server identifies the pod based on the remote address of the request and then queries the k8s (through MIC) for a matching Azure identity. It then makes an Azure Active Directory Authentication Library ([ADAL](https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-authentication-libraries)) request to get the token for the client id and returns as a response to the request. If the request had client id as part of the query it validates it against the admin configured client id. - -Similarly a host can make an authorization request to fetch Service Principal Token for a resource directly from the NMI host endpoint (http://127.0.0.1:2579/host/token/). The request must include the pod namespace `podns` and the pod name `podname` in the request header and the resource endpoint of the resource requesting the token. The NMI server identifies the pod based on the `podns` and `podname` in the request header and then queries k8s (through MIC) for a matching azure identity. Then NMI makes an ADAL request to get a token for the resource in the request, returns the `token` and the `clientid` as a response to the request. - -An example cURL command: - -```bash -curl http://127.0.0.1:2579/host/token/?resource=https://vault.azure.net -H "podname: nginx-flex-kv-int" -H "podns: default" -``` +* [Demo](#demo) +* [Components](#components) +* [What To Do Next?](#what-to-do-next) +* [Code of Conduct](#code-of-conduct) ## Getting Started -### Prerequisites +### Prerequisites -A running k8s cluster on Azure using AKS or AKS Engine +You will need a Kubernetes cluster running on Azure, either managed by [AKS] or provisioned with [AKS Engine]. -### Deploy the aad-pod-identity infra +### 1. Create the Deployment -Deploy the infrastructure with the following command to deploy MIC, NMI, and the MIC CRDs on an RBAC enabled cluster. +AAD Pod Identity consists of the Managed Identity Controller (MIC) deployment, the Node Managed Identity (NMI) daemon set, and several standard and custom resources. For more information, see [Components]. -``` -kubectl create -f https://raw.githubusercontent.com/Azure/aad-pod-identity/master/deploy/infra/deployment-rbac.yaml -``` -and for non-RBAC clusters: -``` -kubectl create -f https://raw.githubusercontent.com/Azure/aad-pod-identity/master/deploy/infra/deployment.yaml -``` -### Create User Azure Identity +Run this command to create the `aad-pod-identity` deployment on an RBAC-enabled cluster: -Get the client id and resource id for the identity -``` -az identity create -g -n +```shell +kubectl apply -f https://raw.githubusercontent.com/Azure/aad-pod-identity/master/deploy/infra/deployment-rbac.yaml ``` -### Install User Azure Identity on k8s cluster - -Edit and save this as aadpodidentity.yaml - -Set `type: 0` for User Assigned MSI; `type: 1` for Service Principal +Or run this command to deploy to a non-RBAC cluster: +```shell +kubectl apply -f https://raw.githubusercontent.com/Azure/aad-pod-identity/master/deploy/infra/deployment.yaml ``` + +### 2. Create an Azure Identity + +Run this [Azure CLI] command, and take note of the `clientId` and `id` values it returns: + +```shell +az identity create -g -n -o json +``` + +Here is an example of the output: + +```json +$ az identity create -g myresourcegroup -n myidentity -o json +{ + "clientId": "00000000-0000-0000-0000-000000000000", + "clientSecretUrl": "https://control-eastus.identity.azure.net/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/myresourcegroup/providers/Microsoft.ManagedIdentity/userAssignedIdentities/myidentity/credentials?tid=00000000-0000-0000-0000-000000000000&oid=00000000-0000-0000-0000-000000000000&aid=00000000-0000-0000-0000-000000000000", + "id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/myresourcegroup/providers/Microsoft.ManagedIdentity/userAssignedIdentities/myidentity", + "location": "eastus", + "name": "myidentity", + "principalId": "00000000-0000-0000-0000-000000000000", + "resourceGroup": "myresourcegroup", + "tags": {}, + "tenantId": "00000000-0000-0000-0000-000000000000", + "type": "Microsoft.ManagedIdentity/userAssignedIdentities" +} +``` + +### 3. Install the Azure Identity + +Save this Kubernetes manifest to a file named `aadpodidentity.yaml`: + +```yaml apiVersion: "aadpodidentity.k8s.io/v1" kind: AzureIdentity metadata: - name: + name: spec: - type: 0 - ResourceID: /subscriptions//resourcegroups//providers/Microsoft.ManagedIdentity/userAssignedIdentities/ - ClientID: + type: 0 + ResourceID: /subscriptions//resourcegroups//providers/Microsoft.ManagedIdentity/userAssignedIdentities/ + ClientID: ``` -``` -kubectl create -f aadpodidentity.yaml +Replace the placeholders with your user identity values. Set `type: 0` for user-assigned MSI or `type: 1` for Service Principal. + +Finally, save your changes to the file, then create the `AzureIdentity` resource in your cluster: + +```shell +kubectl apply -f aadpodidentity.yaml ``` -### Understanding Namespaced identities -The system will match `pod` to `identity` across namespaces by default. This behavior can be modified to match to pods within the namespace that holds `AzureIdentity` by +### 4. (Optional) Match Pods in the Namespace -1. On Azure Identity basis, by adding `aadpodidentity.k8s.io/Behavior: namespaced` annotation (You have to add the annotation on each `AzureIdentity` you want to apply this behavior on). -2. Default namespaced behavior on all identities by adding `--forceNamespaced=true` argument on the command line or declare `FORCENAMESPACED=true` environment variable (for both `nmi` and `mic`). +By default, AAD Pod Identity matches pods to identities across namespaces. To match only pods in the namespace containing `AzureIdentity`, use one of these techniques: +* Attach a `aadpodidentity.k8s.io/Behavior: namespaced` [annotation] to each `AzureIdentity` resource. -### Install Pod to Identity Binding on k8s cluster + Here is the `AzureIdentity` manifest from the previous step with this annotation added: -Edit and save this as aadpodidentitybinding.yaml. Note the AzureIdentity name must match the one chosen in aadpodidentity.yaml. -``` + ```yaml + apiVersion: "aadpodidentity.k8s.io/v1" + kind: AzureIdentity + metadata: + name: + annotations: + - aadpodidentity.k8s.io/Behavior: namespaced + spec: + type: 0 + ResourceID: /subscriptions//resourcegroups//providers/Microsoft.ManagedIdentity/userAssignedIdentities/ + ClientID: + ``` + +* Add the `--forceNamespaced` command line argument or set the `FORCENAMESPACED=true` environment variable when starting both the MIC and NMI components. + + Here is a section from the MIC deployment which adds *both* the command line argument and the environment variable for illustration. Pick one approach and use it to update both the MIC deployment and the NMI daemon set. + + ```yaml + spec: + containers: + - name: mic + image: "mcr.microsoft.com/k8s/aad-pod-identity/mic:1.3" + imagePullPolicy: Always + args: + - mic + - "--cloudconfig=/etc/kubernetes/azure.json" + - "--logtostderr" + - "--forceNamespaced" + env: + - name: FORCENAMESPACED + value: "true" + ``` + +### 5. Install the Azure Identity Binding + +Save this Kubernetes manifest to a file named `aadpodidentitybinding.yaml`: + +```yaml apiVersion: "aadpodidentity.k8s.io/v1" kind: AzureIdentityBinding metadata: - name: demo1-azure-identity-binding + name: demo1-azure-identity-binding spec: - AzureIdentity: - Selector: