Skip to content

Commit 6875e0c

Browse files
authored
SAML Troubleshooting. More details about what to look for in XML response (#1184)
1 parent e56fe9d commit 6875e0c

File tree

1 file changed

+35
-27
lines changed
  • install-and-configure/advanced-configuration/user-management-saml

1 file changed

+35
-27
lines changed

install-and-configure/advanced-configuration/user-management-saml/README.md

Lines changed: 35 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,15 @@ Kubecost supports single sign-on (SSO) and role-based access control (RBAC) with
88

99
## Overview of features
1010

11-
* User authentication (`.Values.saml`): SSO provides a simple mechanism to restrict application access internally and externally
12-
* Pre-defined user roles (`.Values.saml.rbac`):
13-
* `admin`: Full control with permissions to manage users, configure model inputs, and application settings.
14-
* `readonly`: User role with read-only permission.
15-
* `editor`: Role can change and build alerts and reports, but cannot edit application settings and otherwise functions as read-only.
16-
* Custom access roles (_filters.json_): Limit users based on attributes or group membership to view a set of namespaces, clusters, or other aggregations
11+
- User authentication (`.Values.saml`): SSO provides a simple mechanism to restrict application access internally and externally
12+
- Pre-defined user roles (`.Values.saml.rbac`):
13+
- `admin`: Full control with permissions to manage users, configure model inputs, and application settings.
14+
- `readonly`: User role with read-only permission.
15+
- `editor`: Role can change and build alerts and reports, but cannot edit application settings and otherwise functions as read-only.
16+
- Custom access roles (_filters.json_): Limit users based on attributes or group membership to view a set of namespaces, clusters, or other aggregations
1717

1818
{% code overflow="wrap" %}
19+
1920
```yaml
2021
# EXAMPLE CONFIGURATION
2122
# View setup guides below, for full list of Helm configuration values
@@ -38,18 +39,19 @@ saml:
3839
- "kubecost_superusers"
3940
- name: readonly
4041
enabled: true
41-
assertionName: "kubecost_group"
42+
assertionName: "kubecost_group"
4243
assertionvalues:
4344
- "kubecost_users"
4445
customGroups:
4546
- assertionName: "kubecost_group"
4647
```
48+
4749
{% endcode %}
4850
4951
## SAML setup guides
5052
51-
* [Microsoft Entra ID (formerly Azure AD) SAML Integration for Kubecost](microsoft-entra-id-saml-integration-for-kubecost.md)
52-
* [Okta setup guide](okta-saml-integration.md)
53+
- [Microsoft Entra ID (formerly Azure AD) SAML Integration for Kubecost](microsoft-entra-id-saml-integration-for-kubecost.md)
54+
- [Okta setup guide](okta-saml-integration.md)
5355
5456
{% hint style="info" %}
5557
All SAML 2.0 providers also work. The above guides can be used as templates for what is required.
@@ -59,25 +61,29 @@ All SAML 2.0 providers also work. The above guides can be used as templates for
5961
6062
When SAML SSO is enabled in Kubecost, the following ports will require authentication:
6163
62-
* `service/kubecost-cost-analyzer`: ports 9003 and 9090
63-
* `service/kubecost-aggregator`: port 9004
64+
- `service/kubecost-cost-analyzer`: ports 9003 and 9090
65+
- `service/kubecost-aggregator`: port 9004
6466

6567
{% code overflow="wrap" %}
68+
6669
```sh
6770
curl -L 'http://kubecost.mycompany.com/model/allocation?window=1d' \
6871
-H 'Cookie: token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOlsiYWRtaW4iLCJncm91cDprdWJlY29zdF9hZG1pbiIsImdyb3VwOmFkbWluQG15Y29tcGFueS5jb20iXSwiZXhwIjoxNjkwMzA2MjYwLjk0OTYyMX0.iLbUuMo0eYhNg0hzv_EEHLIX5Z0du4woPevX3wEnAh8'
6972
```
73+
7074
{% endcode %}
7175

7276
For admins, Kubecost additionally exposes unauthenticated APIs:
7377

7478
`service/kubecost-cost-analyzer`: port 9007
79+
7580
```sh
7681
kubectl port-forward service/kubecost-cost-analyzer 9007:9007
7782
curl -L 'localhost:9007/allocation?window=1d&aggregate=namespace'
7883
```
7984

8085
`service/kubecost-aggregator`: port 9008
86+
8187
```sh
8288
kubectl port-forward service/kubecost-aggregator 9008:9008
8389
curl -L 'localhost:9008/allocation?window=1d&aggregate=namespace'
@@ -99,14 +105,13 @@ readonly: true
99105

100106
## Troubleshooting
101107

102-
1. Disable SAML and confirm the `cost-analyzer` pod starts. If `kubecostAggregator.enabled` is unspecified or `true` in the _values.yaml_ file, confirm that the `aggregator` pod starts.
103-
2. If Step 1 is successful, but the pod is crashing or never enters the ready state when SAML is added, it is likely there is panic when loading or parsing SAML data.
104-
* If `kubecostAggregator.enabled` is `true` or unspecified in _values.yaml_, run `kubectl logs statefulsets/kubecost-aggregator` and `kubectl logs deploy/kubecost-cost-analyzer`
105-
* If `kubecostAggregator.enabled` is `false` in _values.yaml_, run `kubectl logs services/kubecost-aggregator` and `kubectl logs deploy/kubecost-cost-analyzer`
108+
1. Disable SAML and verify that the `cost-analyzer` pod starts successfully. If the `aggregator` pod is enabled, verify it also starts successfully.
109+
2. If Step 1 is successful but re-enabling SAML causes the pod to crash or never enter the ready state, it is likely there is panic when parsing SAML data. Run `kubectl logs services/kubecost-aggregator` for further details.
106110

107-
If you’re supplying the SAML from the address of an Identity Provider Server, `curl` the SAML metadata endpoint from within the `kubecost` pod and ensure that a valid XML EntityDescriptor is being returned and downloaded. The response should be in this format:
111+
If you have specified a `.Values.saml.idpMetadataURL`, try running `curl` from within the `kubecost` pod and ensure that a valid XML EntityDescriptor is being returned and downloaded. The response should be in the format shown below. Kubecost expects both `entityID` and `IDPSSODescriptor.SingleSignOnService.Location` to exist in the response.
108112

109113
{% code overflow="wrap" %}
114+
110115
```bash
111116
$ kubectl exec deployment/kubecost-cost-analyzer -c cost-analyzer-frontend -n kubecost -it -- /bin/sh
112117
$ curl https://dev-elu2z98r.auth0.com/samlp/metadata/c6nY4M37rBP0qSO1IYIqBPPyIPxLS8v2
@@ -135,6 +140,7 @@ $ curl https://dev-elu2z98r.auth0.com/samlp/metadata/c6nY4M37rBP0qSO1IYIqBPPyIPx
135140
</IDPSSODescriptor>
136141
</EntityDescriptor>
137142
```
143+
138144
{% endcode %}
139145

140146
### Common SAML errors
@@ -147,19 +153,21 @@ Contact your SAML admin to find the URL on your identity provider that serves th
147153

148154
Certain metadata URLs could potentially return an EntitiesDescriptor, instead of an EntityDescriptor. While Kubecost does not currently support using an EntitiesDescriptor, you can instead copy the EntityDescriptor into a new file you create called metadata.xml:
149155

150-
* Download the XML from the metadata URL into a file called _metadata.xml_
151-
* Copy all the attributes from `EntitiesDescriptor` to the `EntityDescriptor` that are not present.
152-
* Remove the `<EntitiesDescriptor>` tag from the beginning.
153-
* Remove the `</EntitiesDescriptor>` from the end of the XML file.
156+
- Download the XML from the metadata URL into a file called _metadata.xml_
157+
- Copy all the attributes from `EntitiesDescriptor` to the `EntityDescriptor` that are not present.
158+
- Remove the `<EntitiesDescriptor>` tag from the beginning.
159+
- Remove the `</EntitiesDescriptor>` from the end of the XML file.
154160

155161
You are left with data in a similar format to the example below:
156162

157163
{% code overflow="wrap" %}
164+
158165
```xml
159166
<EntityDescriptor xmlns="urn:oasis:names:tc:SAML:2.0:metadata" xmlns:dsig="http://www.w3.org/2000/09/xmldsig#" entityID="kubecost-entity-id">
160-
....
167+
....
161168
</EntityDescriptor>
162169
```
170+
163171
{% endcode %}
164172

165173
Then, you can upload the EntityDescriptor to a secret in the same namespace as kubecost and use that directly.
@@ -170,13 +178,13 @@ To use this secret, in your helm values set metadataSecretName to the name of th
170178

171179
```yaml
172180
saml:
173-
metadataSecretName: metadata-secret
174-
idpMetadataURL: “”
181+
metadataSecretName: "metadata-secret"
182+
idpMetadataURL: ""
175183
```
176184

177185
**Invalid NameID format**
178186

179-
On Keycloak, if you receive an Invalid NameID format error, you should set the option force nameid format in Keycloak. See [Keycloak docs](https://www.keycloak.org/documentation) for more details.
187+
On Keycloak, if you receive an "Invalid NameID format" error, you should set the option "force nameid format" in Keycloak. See [Keycloak docs](https://www.keycloak.org/documentation) for more details.
180188

181189
**Users of CSI driver for storing SAML secret**
182190

@@ -186,15 +194,15 @@ For users who want to use CSI driver for storing SAML secret, we suggest this [g
186194

187195
From a [PingIdentity article](https://support.pingidentity.com/s/article/Cannot-provide-requested-name-identifier-qualified-with-SampleNameNEW):
188196

189-
> An alternative solution is to add an attribute called "SAML\_SP\_NAME\_QUALIFIER" to the connection's attribute contract with a TEXT value of the requested SPNameQualifier. When you do this, select the following for attribute name format: `urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified`
197+
> An alternative solution is to add an attribute called `SAML_SP_NAME_QUALIFIER` to the connection's attribute contract with a TEXT value of the requested SPNameQualifier. When you do this, select the following for attribute name format: `urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified`
190198

191-
On the PingID side: specify an attribute contract “SAML\_SP\_NAME\_QUALIFIER” with the format `urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified`.
199+
On the PingID side: specify an attribute contract `SAML_SP_NAME_QUALIFIER` with the format `urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified`.
192200

193201
On the Kubecost side: in your Helm values, set `saml.nameIDFormat` to the same format set by PingID:
194202

195203
```yaml
196204
saml:
197-
nameIDFormat: urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified
205+
nameIDFormat: "urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"
198206
```
199207

200208
Make sure `audienceURI` and `appRootURL` match the entityID configured within PingFed.

0 commit comments

Comments
 (0)