Argo CD Practical Tutorial 08

service account

Service accounts are accounts we use for authentication automation operations, such as CI/CD pipelines. They should not be tied to a user, because we don't want our pipeline to start failing if we disable that user or restrict its permissions. Service accounts should have strict access controls, and should not be allowed to perform more operations than the pipeline requires, and actual users may need to access more resources.
There are two ways to create a service account in Argo CD: one is to use a local user (just use the apiKey and remove the login part), the other is to use project roles and assign tokens to those roles.

local service account

Now, we will create a separate local account with only the specified apiKey capabilities. This way the user doesn't have a password for the UI or CLI and can only access it after we generate an API key for them (thus gaining CLI or direct API access). We'll also set specific permissions on it; for example, we'll allow it to sync specific apps.
We will modify the argocd cm ConfigMap to add a new service account user, which we will
name gitops-ci:

apiVersion: v1
kind: ConfigMap
metadata:
	name: argocd-cm
data:
	accounts.alina: apiKey, login
	accounts.gitops-ci: apiKey
	admin.enabled: "false"

Commit and push it to the remote so we can get the new account up and running. After we have a new account created, we need to run a command to generate an access token. The problem here is that the alina user does not have permission to do so, and the admin account is disabled. we can

Re-enable management, but this is not a good practice, because we may always forget to disable it again, or just keep it enabled for a long time. Normally, we should disable admin in all local users only after we are done with the setup. However, we may need to create new ones at any time because of new people joining our team, or new scenarios being automated through the pipeline.
So, let's see how to assign permission to update accounts to user alina. To do this, we'll modify the argocd-rbac-cm.yaml file to create a new role called role:userupdate for user updates, which we then assign to the user (lines defining policies start with p, and user or group links to roles whose lines start with g):

apiVersion: v1
kind: ConfigMap
metadata:
	name: argocd-rbac-cm
data:
	policy.default: role:readonly
	policy.csv: |
		p, role:user-update, accounts, update, *, allow
		p, role:user-update, accounts, get, *, allow
		g, alina, role:user-update

Commit, to push the changes to the remote, and make sure Argo CD applies them. Now we can run
the command to create the token (we assume you are logged in as user alina using the CLI):

argocd account generate-token -a gitops-ci

The output should look like this (it's the account token):

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiIzZTc2NWI5Ny04MG
YyLTRkODUtYTkzYi1mNGIzMjRkYTc0ODciLCJpYXQiOjE2MzQxNDkyODksImlzc
yI6ImFyZ29jZCIsIm5iZiI6MTYzNDE0OTI4OSwic3ViIjoiZ2l0b3BzLWNpOmFw
aUtleSJ9.azbvrvckSDevFOG6Tun9nJV0fEMcMpI9Eca9Q5F2QR4

An easy way to check if your newly generated token is working is to run the argocd
account get user info command. We can run it once with the logged-in user, and then
verify the token with . Here, I just
pass the --auth-token parameter for the token (for logged-in users). The --auth-token flag is a generic flag, meaning it
can be used with any command (of course you'll have another token, so don't forget to replace it):

argocd account get-user-info --authtoken eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiIzZTc2NWI5
Ny04MGYyLTRkODUtYTkzYi1mNGIzMjRkYTc0ODciLCJpYXQiOjE2MzQxNDkyODk
sImlzcyI6ImFyZ29jZCIsIm5iZiI6MTYzNDE0OTI4OSwic3ViIjoiZ2l0b3BzLW
NpOmFwaUtleSJ9.azbvrvckSDevFOG6Tun9nJV0fEMcMpI9Eca9Q5F2QR4

The output should be similar to this:

Logged In: true
Username: gitops-ci
Issuer: argocd
Groups:

For a newly created service account, since we didn't specify any permissions, it will use the default
one, which is read-only access. Of course, creating such a token with only read access doesn't make
much sense. Typically, it should do things like register a new cluster or unregister it
(this is usually done in an imperative way - by running commands), create or delete users, create
applications, sync it, etc. We can't set up local accounts as
RBAC groups, we can only have roles and assign local users to roles. We'll take a look at how groups work
when we discuss SSO users later in this chapter. For a complete list of resources and operations
available in the RBAC ConfigMap for your local account, you can check the official documentation:
https://argo-cd.readthedocs.io/en/stable/operator-manual/rbac/ #rbacresources - and action.

Project roles and tokens

Project roles are the second option we can use for service accounts. Application projects are a way for us to apply some constraints to the application definition. From where we can set up the repository we get the state, the target cluster, and the namespaces that can be deployed and even filter the types of resources we can install (for example, we can declare that using a project a secret cannot be deployed). In addition to this, it is possible to create project roles and specify the types of operations that are allowed to be performed, and tokens can then be assigned to the roles.

When the Argo CD is installed, it also comes with a default project, actually called the default project, that doesn't have any restrictions set on its applications (everything is set to allow: '*'). To show how a project works with its token, we'll create a new project and use it with an existing argocd application. Once we have it, we'll need to create a role for the project, create a role for the role, and create a token.

We will create a new file called argocd-proj.yaml and store it in the same file as the argo-app.yaml file (these files can also be found in our official repo at https://github.com /PacktPublishing/ArgoCD practice folder in ch04/kustomize installation). After we create it, we will need to apply it manually (we will see in Chapter 5 Argo CD Bootstrap K8s cluster, how application mode helps us create all these applications and application projects automatically). This is the content of the current file. You can view restricted namespaces and clusters for destinations, and we can only load state from a fixed repo. We also added new roles called Read and Sync, for which we allow all applications to perform fetch and sync operations According to AppProject:

apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
  name: argocd
spec:
  roles:
    - name: read-sync
      description: read and sync privileges
      policies:
        - p, proj:argocd:read-sync, applications, get, argocd/*, allow
        - p, proj:argocd:read-sync, applications, sync, argocd/*, allow
  clusterResourceWhitelist:
    - group: '*'
      kind: '*'
  description: Project to configure argocd self-manage application
  destinations:
    - namespace: argocd
      server: https://kubernetes.default.svc
  sourceRepos:
    - https://github.com/PacktPublishing/ArgoCD-in-Practice.git

We'll use kubectl apply to apply the AppProject to the cluster:
kubectl apply -n argocd –f argocd-proj.yaml
the command output should look similar to the following:
appproject.argoproj.io/argocd created
We'll then modify the argocd application to start using this new AppProject, from project: defaults to project:argocd in the definition. Now, apply the updated file to the cluster using kubectl apply (the full argocd-app.yaml file can be installed at https://github.com/PacktPublishing/ArgoCD-in-Practice in ch04/kustomize):
kubectl apply -n argocd -f argocd-app.yaml

We should now be ready to generate tokens for the read and sync roles we created. This needs to be done synchronously via the CLI or UI, so we can retrieve generated tokens We can run CLI commands with user alina, but we get an error because it doesn't have the required permissions:
FATA[0000] rpc error: code = PermissionDenied desc = permission denied: projects, update, argocd, sub: alina, iat: 2021-10-16T10:16:33Z

Let's add the required permissions by modifying the RBAC ConfigMap. I'm just pasting the policy.
The csv part, this time, I'll limit myself to our exact project, called argocd:

policy.csv: |
	p, role:user-update, accounts, update, *, allow
	p, role:user-update, accounts, get, *, allow
	p, role:user-update, projects, update, argocd, allow
	g, alina, role:user-update

Don't forget to commit and push it to the remote so our changes will be Argo CD'd and applied to the cluster. Afterwards, we can generate the token using the following command
argocd proj role create-token argocd read-sync

replied as below:

Create token succeeded for proj:argocd:read-sync.
ID: ccdc5906-11fc-483b-8e8d-0511c6f28978
Issued At: 2021-10-16T13:44:19+03:00
Expires At: Never
Token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJjY2RjN
TkwNi0xMWZjLTQ4M2ItOGU4ZC0wNTExYzZmMjg5NzgiLCJpYXQiOjE2MzQzODEw
NTksImlzcyI6ImFyZ29jZCIsIm5iZiI6MTYzNDM4MTA1OSwic3ViIjoicHJvajp
hcmdvY2Q6cmVhZC1zeW5jIn0.R02VHylpb4aPjtpd5qLOXHpELGOVgnelCJr3q8
bGU5Y

I can now use this token to start a manual sync for all apps under argocdAppProject.
We have only one application and it has the same name as AppProject, argocd. We can see that if we try to call sync with the logged in user alina, we will get a permission denied error as shown below which can be seen in the output of the following command:
argocd app sync argocd

The error is as follows:

FATA[0000] rpc error: code = PermissionDenied desc = permission
denied: applications, sync, argocd/argocd, sub: alina, iat:
2021-10-16T10:16:33Z

Using the generated token, the command becomes:

argocd app sync argocd --auth-token eyJhbGciOiJIUzI1NiIsInR5cCI
6IkpXVCJ9.eyJqdGkiOiJjY2RjNTkwNi0xMWZjLTQ4M2ItOGU4ZC0wNTExYzZmM
jg5NzgiLCJpYXQiOjE2MzQzODEwNTksImlzcyI6ImFyZ29jZCIsIm5iZiI6MTYz
NDM4MTA1OSwic3ViIjoicHJvajphcmdvY2Q6cmVhZC1zeW5jIn0.R02VHylpb4a
Pjtpd5qLOXHpELGOVgnelCJr3q8bGU5Y

The output is very long as it starts enumerating all the resources our Argo CD application has mounted along with their status, which means the sync is working. Also available from the sync status in the UI (go to the argocd app, on its page you should have a sync status button showing details about the last sync started): every token we generate is saved
insert image description here
to in the project role. We can check how long it is used, its expiry date and whether it is time to rotate it. We can also set an expiration date for it to use it for a limited time if we plan. Otherwise, setting a hard deadline for when we need updates would require strict discipline from the engineers managing Argo CD. In my case, I generally have a tendency to defer quarterly reviews of access controls by a week or two to identify expiration dates that could lead to plumbing failures.

Note – Tokens with sync actions only Let tokens (from local accounts or project roles) only perform sync actions if we can allow the app to sync automatically? I think therefore a valid scenario is to still allow the app to sync automatically, but set a
larger timeout, say 10-15 minutes (this reduces system load and increases its performance). However, after we commit to the GitOps repo, we can call sync also from the pipeline.

Project roles can only be used on the resources of the application and those applications need to perform operations under the project for which the role was created, so their scope is very limited. Actually, however, it's these limitations that turn them into good candidates for use in our pipeline, because if they are compromised for any reason, the attack surface is reduced.

Guess you like

Origin blog.csdn.net/github_35631540/article/details/131412425