Closed eyupdzhanY1 closed 1 year ago
If there is an example SAML configuration in okta would help this issue i believe.
You can grab your metadata from https://k8sou.domain.com/auth/forms/saml2_rp_metadata.jsp (assuming you've gotten openunison deployed?). Curious, why use SAML2 with Okta instead of OIDC?
Not in our product plan with okta, oidc requires extra fees as i get to learn.
@eyupdzhanY1 were you able to upload the saml2 metadata?
Upload it where exactly ? @mlbiam I can access it through mentioned link.
ugh. didn't realize okta wouldn't let you just run let you upload your metadata. i'll test it out and get you specific instructions.
this should get you what you need.
Thank a lot! Will try this on monday and post an update.
Login is successful but I am unable to access dashboard, and in the attributes page there is only user name with email exist. user1@domain.com, in the user CRD there is my user generated but instead of "1" in the user name we have "x-49-x" and instead of @ there is "x-64-x". How can I assign this user role in the ClusterRoleBinding User spec looks like this. And groups are really empty, does it mean no information passed to openunison from okta?
spec:
email: ''
first_name: ''
groups: []
last_name: ''
sub: user1@domain.com
uid: userx-49-xx-64-xdomain.com
I tried these access user names. None gave me access to dashboard.
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: cluster-admins
subjects:
- kind: User
name: https://k8sou.domain.com/auth/idp/k8sIdp#userx-49-xx-64-xdomain.com
- kind: User
name: user1@domain.com
- kind: User
name: userx-49-xx-64-xdomain.com
roleRef:
kind: ClusterRole
name: cluster-admin
apiGroup: rbac.authorization.k8s.io
Login is successful but I am unable to access dashboard,
Can you provide some details? What do you see on the screen?
only user name with email exist.
Your username is whatever you specified in the Application username section of your SAML2 Okta configuraiton. By default it's your Okta username. Looking at your User
object I see user1@domain.com
. Is this not what you were expecting?
he user CRD there is my user generated but instead of "1" in the user name we have "x-49-x" and instead of @ there is "x-64-x"
This is only used internally by OpenUnison. The x-49-x
is used to make sure that any username can be translated into a kubernetes name with its DNS restrictions. It can be ignored. The important field is sub
I tried these access user names. None gave me access to dashboard.
this should work:
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: cluster-admins
subjects:
- kind: User
name: user1@domain.com
roleRef:
kind: ClusterRole
name: cluster-admin
apiGroup: rbac.authorization.k8s.io
That said, you're using AKS, right? Did you enable impersonation in your values.yaml? (enable_impersonation: true
)
Login is successful but I am unable to access dashboard,
Can you provide some details? What do you see on the screen?
only user name with email exist.
Your username is whatever you specified in the Application username section of your SAML2 Okta configuraiton. By default it's your Okta username. Looking at your User
object I see user1@domain.com
. Is this not what you were expecting?
he user CRD there is my user generated but instead of "1" in the user name we have "x-49-x" and instead of @ there is "x-64-x"
This is only used internally by OpenUnison. The x-49-x
is used to make sure that any username can be translated into a kubernetes name with its DNS restrictions. It can be ignored. The important field is sub
I tried these access user names. None gave me access to dashboard.
this should work:
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: cluster-admins
subjects:
- kind: User
name: user1@domain.com
roleRef:
kind: ClusterRole
name: cluster-admin
apiGroup: rbac.authorization.k8s.io
That said, you're using AKS, right? Did you enable impersonation in your values.yaml? (enable_impersonation: true
)
@mlbiam I am using AKS, and impersonation was set to false. Enabled it now.
This is how binding was done.
subjects:
- kind: User
name: "https://k8sou.com/auth/idp/k8sIdp#user1@domain.com"
Odd, same thing we saw in https://github.com/OpenUnison/openunison-k8s/issues/70#issuecomment-1478330257. Try following the same steps?
Right, delete the ou-tls-certificate
Secret
and redeploy. That will force the operator to create a new secret with the correct host name for your API proxy
@mlbiam The secret does not exist but network.createIngressCertificate is false.
Oh, then how are you generating the certificate?
I am not, it all sits behind nginx, and there is load balancer IP.
so it's a wildcard certificate? is your network.api_server_host
set to a DNS entry that points to that NGINX? Please post your values.yaml
Wildcard domains all point there *.test.domain.com , and ingress entries forward to service in openunison correct me if i am wrong.
network:
openunison_host: "k8sou.test.domain.com"
dashboard_host: "k8sdb.test.domain.com"
api_server_host: "k8sapi.test.domain.com"
session_inactivity_timeout_seconds: 900
k8s_url: https://hcp.eastus2.azmk8s.io:443
force_redirect_to_tls: true
createIngressCertificate: false
ingress_type: nginx
ingress_annotations: {}
cert_template:
ou: "Kubernetes"
o: "domain"
l: "Production Cluster"
st: "East US 2"
c: "USA"
image: docker.io/tremolosecurity/openunison-k8s
myvd_config_path: "WEB-INF/myvd.conf"
k8s_cluster_name: openunison-cp
enable_impersonation: true
impersonation:
use_jetstack: true
jetstack_oidc_proxy_image: docker.io/tremolosecurity/kube-oidc-proxy:latest
explicit_certificate_trust: true
dashboard:
namespace: "kubernetes-dashboard"
cert_name: "kubernetes-dashboard-certs"
label: "k8s-app=kubernetes-dashboard"
service_name: kubernetes-dashboard
require_session: true
certs:
use_k8s_cm: false
trusted_certs:
- name: okta-cert
pem_b64: Certificate in base64
monitoring:
prometheus_service_account: system:serviceaccount:monitoring:prometheus-k8s
saml:
idp_url: "https://domain.okta.com/app/STRING/sso/saml/metadata"
network_policies:
enabled: false
ingress:
enabled: true
labels:
app.kubernetes.io/name: ingress-nginx
monitoring:
enabled: true
labels:
app.kubernetes.io/name: monitoring
apiserver:
enabled: false
labels:
app.kubernetes.io/name: kube-system
services:
enable_tokenrequest: false
token_request_audience: api
token_request_expiration_seconds: 600
node_selectors: []
openunison:
replicas: 1
non_secret_data:
K8S_DB_SSO: saml2
PROMETHEUS_SERVICE_ACCOUNT: system:serviceaccount:monitoring:prometheus-k8s
SHOW_PORTAL_ORGS: "false"
secrets: []
html:
image: docker.io/tremolosecurity/openunison-k8s-html
enable_provisioning: false
use_standard_jit_workflow: true
Is the ingress signed by a commercial CA? or is it an internal CA? Is this CA distributed to your workstation where you're running kubectl from?
It is signed by commercial CA, it works fine as long as you are within the company network, had no issues with TLS so far.
run kubectl get nodes --v=11
. Should give some details as to why the cert isn't being accepted by kubectl.
Adding wildcard certificate as ou-tls-certificate secret first, then deploying worked for connection.
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: k8sou-admins
subjects:
- kind: User
name: "user@domain.com"
roleRef:
kind: ClusterRole
name: cluster-admin
apiGroup: rbac.authorization.k8s.io
Worked for me , user is whatever "sub" is under openunison.tremolo.io CRD's user resource.
@mlbiam Thank you again for all the help, reading groups are still a trouble, both saml2 and oidc setup does not work. For oidc we use AzureAD but delegation and scoping seems to be in the way of things.
And okta does not reply with any memberOf fields for saml2.
For oidc we use AzureAD but delegation and scoping seems to be in the way of things.
Your groups are in azuread? Do you sync these groups into Okta?
We do sync , not everything but most groups. I am trying to figure out why saml2 groups appear empty in user CRD.
We do sync , not everything but most groups
in your Okta SAML configuration, what do you have for your Group Attribute Statement? See attached screenshot from my okta deployment:
@mlbiam Yes this was able to get groups that are synced thank you , but still not full AzureAD. Do you know if openunison can only work with delegated user in the azuread setup ? Apps are super limited in our current structure.
but still not full AzureAD.
So just to make sure I understand correctly. Not all groups are synced from AzureAD to Okta, but you need groups that haven't been synced to Okta too?
Do you know if openunison can only work with delegated user in the azuread setup ?
OOTB we can lookup groups in AzureAD if you authenticate to AzureAD. It'll take some YAML, but if you can get a client secret that can lookup users in your AzureAD openunison could lookup groups from azuread based on the loggedin user's upn/email.
If it is delegated permissions i can get read on anything, when it switches to app permissions have to scope and it can not read groups. About saml2 , we got as far as we can , it works and no more info possible from it. AzureAD seems better option if can read groups somehow.
Type: A = Application Permission, D = Delegate Permission
Ver | Type | Method |
---|---|---|
V1 | A,D | GET /groups |
V1 | A,D | GET /groups/{group-id}/permissionGrants |
V1 | A,D | GET /groups/{id} |
V1 | A,D | GET /groups/{id}/memberOf |
V1 | A,D | GET /groups/{id}/members |
V1 | A,D | GET /groups/{id}/owners |
V1 | D | GET /groups/{id}/transitiveMemberOf |
V1 | A,D | GET /groups/{id}/transitiveMembers |
V1 | A,D | GET /groups/delta |
V1 | D | GET /me/memberOf |
V1 | A,D | GET /me/transitiveMemberOf |
V1 | D | GET /users/{id | userPrincipalName}/memberOf |
V1 | A,D | GET /users/{id | userPrincipalName}/transitiveMemberOf |
V1 | A,D | POST /directoryObjects/{id}/checkMemberGroups |
V1 | A,D | POST /directoryObjects/{id}/checkMemberObjects |
V1 | A,D | POST /directoryObjects/{id}/getMemberGroups |
V1 | A,D | POST /directoryObjects/{id}/getMemberObjects |
Type: A = Application Permission, D = Delegate Permission
Ver Type Method V1 A,D GET /groups V1 A,D GET /groups/{group-id}/permissionGrants V1 A,D GET /groups/{id} V1 A,D GET /groups/{id}/memberOf V1 A,D GET /groups/{id}/members V1 A,D GET /groups/{id}/owners V1 D GET /groups/{id}/transitiveMemberOf V1 A,D GET /groups/{id}/transitiveMembers V1 A,D GET /groups/delta V1 D GET /me/memberOf V1 A,D GET /me/transitiveMemberOf V1 D GET /users/{id | userPrincipalName}/memberOf V1 A,D GET /users/{id | userPrincipalName}/transitiveMemberOf V1 A,D POST /directoryObjects/{id}/checkMemberGroups V1 A,D POST /directoryObjects/{id}/checkMemberObjects V1 A,D POST /directoryObjects/{id}/getMemberGroups V1 A,D POST /directoryObjects/{id}/getMemberObjects
We can only do delegated if you're authenticating you to azuread. We can integrate with AzureAD directly if that is easier - https://openunison.github.io/identity%20providers/azuread/ ?
Yes that is what i used to deploy with azuread. Am i missing something there ?
Sorry, I'm very confused. I thought you were using Okta for authentication?
I am sorry for jumping around on the subject. I have 2 values yaml, 1 is for azuread, 1 is for okta saml. Okta saml is a no go because limited amount of groups we can read.
AzureAD has problems reading user groups because of scoping required for app registrations. If used delegated permissions thus using the power's of logged in user, we can read the group.
When a request is made to https://graph.microsoft.com/v1.0/me/memberOf with the app registration, I can read all the groups user is part of. How does openunison request the groups ?
So I dug deep and realized AppRegistration needs to be configured. manifest of app registration should look like this , changes to token version and optional claims. This allows groups info to be inside id_token.
"accessTokenAcceptedVersion": 2,
.
.
.
"optionalClaims": {
"idToken": [
{
"name": "email",
"source": null,
"essential": false,
"additionalProperties": []
},
{
"name": "upn",
"source": null,
"essential": false,
"additionalProperties": []
},
{
"name": "family_name",
"source": null,
"essential": false,
"additionalProperties": []
},
{
"name": "given_name",
"source": null,
"essential": false,
"additionalProperties": []
},
{
"name": "preferred_username",
"source": null,
"essential": false,
"additionalProperties": []
},
{
"name": "groups",
"source": "user",
"essential": true,
"additionalProperties": [
"sam_account_name"
]
}
],
"accessToken": [
{
"name": "groups",
"source": "user",
"essential": true,
"additionalProperties": [
"sam_account_name"
]
}
],
"saml2Token": [
{
"name": "groups",
"source": null,
"essential": false,
"additionalProperties": [
"sam_account_name"
]
}
]
},
Then when values.yaml should be edited to have oidc.claims.groups=groups
oidc:
claims:
groups: groups
In the end finally a group info can be read !
it looks like the samAccountName is available so you don't need the additional lookup. I take it you're working at this point and we can close out this issue?
Yes closing the issue thank you, just wanted to document developments.
If set to base https://k8sou.HOST.com/ it keeps redirected to login splash , what is the correct values ?
Looping networking tab from chrome.