spinnaker: Fiat Service Account causes NPE if the Service Account is not a user in LDAP

Issue Summary:

We create a Fiat service account using FRONT50 API. We run the FIAT Roles sync command to make sure that the new service account information gets synced. However, the sync command fails with a Null Pointer Exception. However, if the Fiat Service Account name happens to be an actual LDAP user, things work and no NPE is thrown. However, creating an LDAP user for every single Fiat Service Account is not a scalable solution for us.

Cloud Provider(s):

I am running Spinnaker 1.9.3 on Kubernetes v1.11.2. Kubernetes is running on an OpenStack cluster inside my company. I use LDAP (MS Active Directory) for AuthC and Groups.

Environment:

My instance of Spinnaker is running on Kubernetes

Feature Area:

Service Accounts, Pipeline Permissions

Description:

While Fiat Service Accounts are not supposed to be tied to the backend being used for Authentication (in our case, LDAP), we are finding that we cannot create a service account and sync it. Attempting to do that causes 500 Server Error and Null Pointer Exception in the Fiat logs. However, if the Service Account is created with a name that matches an LDAP user, it works fine. Tying Fiat Service Accounts to the Authentication backend User source seems like a bug to me

Steps to Reproduce:

Here’s how you can reproduce it. I am sure this issue will show up with other Group Providers as well, but I have only tested this where the Group Provider is LDAP Groups:

I create a service account using the following command:

curl -X POST \
  -H "Content-type: application/json" \
  -d '{ "name": "testsa@managed-service-account", "memberOf": ["code-phwhitin"] }' \
  $FRONT50/serviceAccounts | jq .

It successfully creates the service account, as this API call confirms it:

curl -s $FRONT50/serviceAccounts | jq .

Now, code-phwhitin is an LDAP group with just one LDAP user (phwhitin). Before creating this service account, this user did not have access to any Fiat Service Account.

Since I am not sure if the sync command is mandatory after creating a new service account, I decided to run this command to see if the new service account testsa@managed-service-account got added to the user phwhitin:

curl -s $FIAT/authorize/phwhitin | jq .

Turned out, it did not. So, I dutifully run the sync command:

curl -X POST $FIAT/roles/sync

This command fails with this error:

{
  "timestamp" : 1538008639775,
  "status" : 500,
  "error" : "Internal Server Error",
  "exception" : "java.lang.NullPointerException",
  "message" : "No message available"
}

I see the following errors in Fiat log. I have only shown a snippet of it.

spin-fiat-6b96d6447f-8vfx7 fiat 2018-09-27 00:37:19.725  INFO 1 --- [0.0-7003-exec-6] c.n.s.fiat.controllers.RolesController   : [] Full role sync invoked by web request.
spin-fiat-6b96d6447f-8vfx7 fiat 2018-09-27 00:37:19.743  INFO 1 --- [0.0-7003-exec-6] c.n.s.fiat.roles.UserRolesSyncer         : [] Synced anonymous user role.
spin-fiat-6b96d6447f-8vfx7 fiat 2018-09-27 00:37:19.774 ERROR 1 --- [0.0-7003-exec-6] c.n.s.f.r.ldap.LdapUserRolesProvider     : [] Unable to find a single user entry
spin-fiat-6b96d6447f-8vfx7 fiat org.springframework.dao.IncorrectResultSizeDataAccessException: Incorrect result size: expected 1, actual 0
spin-fiat-6b96d6447f-8vfx7 fiat 	at org.springframework.security.ldap.SpringSecurityLdapTemplate.searchForSingleEntryInternal(SpringSecurityLdapTemplate.java:361)
spin-fiat-6b96d6447f-8vfx7 fiat 	at org.springframework.security.ldap.SpringSecurityLdapTemplate$3.executeWithContext(SpringSecurityLdapTemplate.java:318)
spin-fiat-6b96d6447f-8vfx7 fiat 	at org.springframework.ldap.core.LdapTemplate.executeWithContext(LdapTemplate.java:817)
...

You can see the full error log here

I was hoping this error would be benign and that upon running the API, the service account testsa@managed-service-account added to phwhitin

curl -s $FIAT/authorize/phwhitin | jq .

it did not. ☹️

As I said earlier, if the service account name actually matches an actual LDAP user in our LDAP server, the sync API call works like a charm. And therein lies our problem. We really do not want to find ourselves being forced to create an LDAP user for every single Fiat Service account we create.

Additional Details:

Any ideas how we can bypass this without creating an actual LDAP user.


About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Comments: 17 (6 by maintainers)

Most upvoted comments

Thanks @dibyom and @emptywee for your support in releasing this fix! Appreciate your time.

Happy to confirm it’s working very well in my case. Roles are synced and applied to users correctly, and service accounts are available to use in triggers if roles match.

Thanks, @dibyom, and @emptywee The pleasure was really all ours!

😄

Fixed in https://github.com/spinnaker/fiat/pull/269

Thank you for debugging and contributing the fix @smuthuswamy and @indrayam !

@emptywee you can this out now!

Hey @dibyom, Thanks for the fix. @indrayam and I are working on the same project. We would like to test this fix in our dev environment. Is there a docker image/tag created for this fix? Thanks!