Open xkortex opened 3 years ago
I created this sa/clusterrole:
apiVersion: v1
kind: ServiceAccount
metadata:
name: argo-master-sa
namespace: default
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: argo-master-role
rules:
- apiGroups:
- argoproj.io
resources:
- workflows
- workflows/finalizers
verbs:
- get
- list
- watch
- update
- patch
- delete
- create
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: argo-master-binding-ns-argo
namespace: argo
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: argo-master-role
subjects:
- kind: ServiceAccount
name: argo-master-sa
namespace: default
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: argo-master-binding-ns-dry-run
namespace: dry-run
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: argo-master-role
subjects:
- kind: ServiceAccount
name: argo-master-sa
namespace: default
Acquired token:
SECRET=$(kubectl get sa argo-master-sa -o=jsonpath='{.secrets[0].name}')
ARGO_TOKEN="Bearer $(kubectl get secret $SECRET -o=jsonpath='{.data.token}' | base64 --decode)"
Access across namespace with curl:
curl http://localhost:2746/api/v1/workflows/argo -H "Authorization: $ARGO_TOKEN"
{...success...}
curl http://localhost:2746/api/v1/workflows/dry-run -H "Authorization: $ARGO_TOKEN"
{...success...}
And correctly scoped:
curl http://localhost:2746/api/v1/workflows/not-a-ns-this-will-fail-successfully -H "Authorization: $ARGO_TOKEN"
{"code":7,"message":"workflows.argoproj.io is forbidden: User \"system:serviceaccount:default:argo-master-sa\" cannot list resource \"workflows\" in API group \"argoproj.io\" in the namespace \"not-a-ns-this-will-fail-successfully\""}
import os, sys, time, re, json
import argo
import requests
import yaml
from argo.workflows.client import (ApiClient,
WorkflowServiceApi, InfoServiceApi,
Configuration,
V1alpha1WorkflowCreateRequest)
WORKFLOW = 'https://raw.githubusercontent.com/argoproj/argo-workflows/master/examples/hello-world.yaml'
resp = requests.get(WORKFLOW)
manifest: dict = yaml.safe_load(resp.text)
# argo-master-sa
bearer = "eyJhbGc..."
config = Configuration(host="http://localhost:2746", api_key={'authorization': bearer}, api_key_prefix={'authorization': 'Bearer'})
config.debug = True
client = ApiClient(configuration=config)
service = WorkflowServiceApi(api_client=client)
# this works
res = requests.get('http://localhost:2746/api/v1/workflows/argo')
res.json()
# this fails as expected with 403
res = requests.get('http://localhost:2746/api/v1/workflows/dry-run')
res.json()
# this works, we can auth this with our bearer token
res = requests.get('http://localhost:2746/api/v1/workflows/dry-run', headers={"Authorization": "Bearer " + bearer})
res.json()
# this works, since it's the default ns
workflows = service.list_workflows('argo')
# this fails despite setting the token in config
workflows = service.list_workflows('dry-run')
workflows
Notably, the service.list_workflows
still works in the argo
namespace, even when the token is bad, which I think means that my environment (a jupyter notebook) and the library defaults succeed with the argo
namespace.
Aha! Limited success by using
client = ApiClient(configuration=config, header_name="Authorization", header_value= "Bearer " + bearer)
but this feels wrong-ish. I feel like there ought to be a way to set the serviceaccount in the config.
Alas, this indeed seems to be incorrect in some fashion, as the workflows are stuck pending in my alternate namespace:
argo list -n dry-run
NAME STATUS AGE DURATION PRIORITY
coinflip-8q944 Pending 19s 0s 0
hello-world-6666d Pending 18h 0s 0
hello-world-s5ls4 Pending 18h 0s 0
argo list -n argo
NAME STATUS AGE DURATION PRIORITY
coinflip-hmf6h Running 4s 4s 0
hello-world-2gsfc Succeeded 18h 10s 0
hello-world-vr5d6 Succeeded 18h 10s 0
This appears to be a duplicate of #26
edit: pretty sure this is a PEBCAK error, it seems this token auth method does work, but my permissions configurations are not idealedit2: ok yeah I think I'm definitely missing something, I get
The user is
system:serviceaccount:argo:argo-server
irrespective of what serivecaccount I use to generate the token.I'm developing a bot which can issue Argo workflows. I'm struggling to work out how to provide authorization through the
Configuration
interface. I've generated anARGO_TOKEN
as per these instructions. Looks like:"eyJhbGciOiJSUzI1NiI..."
, 880 characters of what looks like b64 encoded RS256 token. I'm actually using theargo
serviceaccount so I should have full perms. Works withcurl http://localhost:2746/api/v1/workflows/argo -H "Authorization: $ARGO_TOKEN"
.I feel like I'm configuring
api_key
andapi_key_prefix
wrong. I've tried variations of 'authorization', 'bearer', 'Bearer', etc, and can't get it to stick. The documentation isn't super clear how to use various auth schemes (other than cookieAuth) and I'm wondering if the protocol has drifted.Thanks
Full trace: