Overview
The upcoming release of SHIELD v8 adds support for GitHub and UAA authentication providers. Previous versions of SHIELD only supported basic auth. Many organizations already heavily rely on GitHub and UAA to organize users and permissions within an organization. You will be able to leverage these existing authentication providers to grant access to SHIELD.
Multi-tenancy is also being added. A tenant is a single group that defines the context for interaction with resources in a SHIELD configuration. All retention policies, jobs, backup targets, storage endpoints, and archives belong to a single tenant. Each tenant creates and manages its own target and storage configurations, and tenants are prevented from accessing or viewing another tenant’s configuration.
The rest of this blog explores leveraging groups defined in UAA and mapping these groups to tenants in SHIELD. There are many different ways to mapping tenant roles to UAA groups, you are encouraged to understand these roles and map them to your organization as you see fit.
Use Case
Assume we work at a company where UAA is used to control access to BOSH with the following groups of people:
- Admins are defined in the BOSH deployment manifest’s UAA properties to control the cloud-config and platform level maintenance such as deploying BOSH, Cloud Foundry & SHIELD.
- There are also BOSH Teams defined where members of each of these teams can deploy without having access to the platform deployments or deployments from other BOSH teams.
- There are three BOSH Teams defined with this sandboxed access: Postgres Team, RabbitMQ Team, and Vault Team.
Our goal is for each of these teams to control their own BOSH deployments and also control their own backups and restores with SHIELD without impacting each other. The overall use case looks like:
Implementation
Configuring SHIELD to use UAA is done in two steps:
- Configure UAA groups and membership in BOSH
- Configure the UAA group mappings to SHIELD tenants and roles
Step 1 – Configuring BOSH
We’ve identified a number of groups in our organization which have different access requirements to both BOSH and SHIELD. Below we break down how to turn pieces of the use case into configuration points in the BOSH deployment manifest.
Define BOSH Teams / UAA Groups
In the manifest for BOSH we can define the three teams, one each for the Postgres Team, RabbitMQ Team, and Vault Team:
properties:
uaa:
scim:
groups:
bosh.teams.postgres.admin: Postgres Admin Group
bosh.teams.rabbitmq.admin: RabbitMQ Admin Group
bosh.teams.vault.admin: Vault Admin Group
So that each team can also upload their own stemcells and releases, we also add the groups bosh.read
, bosh.releases.upload
, and bosh.stemcell.upload
as described in the BOSH Teams documentation:
properties:
uaa:
scim:
groups:
bosh.read: BOSH Read Only Access
bosh.releases.upload: BOSH Releases Upload Group
bosh.stemcells.upload: BOSH Stemcell Upload Group
We’ll also add three SHIELD specific UAA groups to make mapping a bit easier to each of the SYSTEM tenant roles understood by SHIELD (admin, manager, engineer):
properties:
uaa:
scim:
groups:
shield.admin: SHIELD System Admin Group
shield.manager: SHIELD System Manager Group
shield.engineer: SHIELD System Engineering Group
Define UAA Users
Now that all the UAA groups have been defined for our use case, the UAA users can be added. UAA users are defined with the usernames and passwords used for authentication. UAA users are associated with one or more UAA groups.
We’ll start with a typical BOSH Admin. These individuals have full access to BOSH and are responsible for deploying and maintaining BOSH, SHIELD, and Cloud Foundry. Normally, this account would be configured with bosh.admin, uaa.admin, scim.read and scim.write
access but we’re also adding shield.admin
to make the mapping clearer in Step 2. Replace admin
with a real person’s name or identifier for your own deployment:
properties:
uaa:
scim:
users:
- name: admin
groups: [shield.admin, bosh.admin, uaa.admin, scim.read, scim.write]
password: admin2
To add a user to the Postgres Team, they will need to be placed in their own BOSH team and be able to upload BOSH releases and stemcells. The same needs to be done for the RabbitMQ and Vault team members and is omitted for brevity. Again, replace postgres.admin
with a real person’s name or identifier.
properties:
uaa:
scim:
users:
- name: postgres.admin
groups: [bosh.teams.postgres.admin, bosh.read, bosh.releases.upload, bosh.stemcells.upload]
password: psq5432
Define a UAA Client
The SHIELD daemon also needs to communicate with UAA to retrieve information about group membership. This is done by configuring a UAA Client, an alternate set of instructions using the uaac
client are described here. The only change you need to make for your own deployment is to the redirect-uri
which will be the URL to the SHIELD daemon:
properties:
uaa:
clients:
shield-dev:
name: S.H.I.E.L.D.
override: true
authorized-grant-types: authorization_code
scope: openid
authorities: uaa.none
access-token-validity: 180
refresh-token-validity: 180
secret: "s.h.i.e.l.d."
redirect-uri: http://localhost:8181/auth/uaa1/redir
Above, the redirect-uri
also contains the name of the UAA instance, called the identifier
, which in this example has the value uaa1
which will be needed later in Step 2. The "name" of the client shield-dev
and the "secret" s.h.i.e.l.d.
will also be needed in Step 2.
Complete BOSH Manifest Snippet
Putting this all together, here is the full snippet we’ll be adding to the BOSH manifest:
properties:
uaa:
scim:
groups:
bosh.read: BOSH Read Only Access
bosh.releases.upload: BOSH Releases Upload Group
bosh.stemcells.upload: BOSH Stemcell Upload Group
bosh.teams.postgres.admin: Postgres Admin Group
bosh.teams.rabbitmq.admin: RabbitMQ Admin Group
bosh.teams.vault.admin: Vault Admin Group
shield.admin: SHIELD System Admin Group
shield.manager: SHIELD System Manager Group
shield.engineer: SHIELD System Engineering Group
users:
- name: admin
groups: [shield.admin, bosh.admin, uaa.admin, scim.read, scim.write]
password: admin2
- name: a.security.engineer
groups: [shield.engineer, bosh.read, scim.read]
password: admin2
- name: postgres.admin
groups: [bosh.teams.postgres.admin, bosh.read, bosh.releases.upload, bosh.stemcells.upload]
password: psq5432
- name: rabbitmq.admin
groups: [bosh.teams.rabbitmq.admin, bosh.read, bosh.releases.upload, bosh.stemcells.upload]
password: rabbit5672
- name: vault.admin
groups: [bosh.teams.vault.admin, bosh.read, bosh.releases.upload, bosh.stemcells.upload]
password: hashi8200
clients:
shield-dev:
name: S.H.I.E.L.D.
override: true
authorized-grant-types: authorization_code
scope: openid
authorities: uaa.none
access-token-validity: 180
refresh-token-validity: 180
secret: "s.h.i.e.l.d."
redirect-uri: http://localhost:8181/auth/uaa1/redir
Now redeploy your BOSH Director so the changes are pushed to the UAA instance on the director.
Note that all of this could have been done using uaac
commands however if you have multiple environments, having the groups, users, and clients defined in the BOSH manifest makes it easier to repeat this configuration. The passwords are also easily cracked in this example, use more secure passwords or let credhub automatically create them for you.
Step 2 – Configure UAA Groups Mapping to SHIELD Tenants
This portion of the configuration is responsible for controlling which authentication providers will be used by SHIELD. This is also where the mapping between UAA Groups, SHIELD Tenants, and Roles are defined. This is done by modifying the deployment manifest for SHIELD.
Define UAA Authentication Provider
Start with the configuring SHIELD to allow uaa
to be one of the authentication providers. At the end of Step 1 we configured a UAA Client for the SHIELD daemon. From this we can extract the client_id
, client_secret
and identifier
.
properties:
uaa:
clients:
shield-dev: #<== Match to client_id:
secret: "s.h.i.e.l.d." #<== Match to client_secret:
redirect-uri: http://localhost:8181/auth/uaa1/redir #<== `uaa1` matches to the identifier:
Now we can start to configure the manifest for SHIELD, the source of information is commented on each line:
auth:
- name: Prod BOSH UAA #<== This text shows up in the SHIELD login page
identifier: uaa1 #<== From the BOSH Manifest
backend: uaa #<== Must be `uaa`, indicates provider type
properties:
client_id: shield-dev #<== From the BOSH Manifest
client_secret: s.h.i.e.l.d. #<== From the BOSH Manifest
uaa_endpoint: https://192.168.50.6:8443 #<== Points to the UAA instance on BOSH
skip_verify_tls: true
Define Mappings – BOSH Admin & Security Admin
First we will start with the mappings for the BOSH Admin and the Security Admin. There is a special tenant, called the SYSTEM tenant, that exists solely to allow SHIELD site operators to assign system-level rights and roles to UAA group members, based on the same rules as tenant-level role assignment.
The SYSTEM tenant has its own set of assignable roles:
- admin – Full control over all of SHIELD.
- manager – Control over tenants and manual role assigments.
- engineer – Control over shared resources like global storage definitions and retention policy templates.
These rights rules are processed until one matches; subsequent rules are skipped.
Here is our use case mapping:
We’ll use the System
tenant and map the UAA group BOSH Admins
are mapped to SHIELD System Admin
role in the use case. We are using both bosh.admin
and shield.admin
in case there were other users defined as bosh.admin
manually through uaac
.
We also will map the UAA group shield.engineer
, which the Security Admin is a part of to the SHIELD System Engineer
, that will have a SHIELD role of engineer
:
auth:
- name: Prod BOSH UAA
properties:
mapping:
- tenant: SYSTEM
rights:
- { scim: bosh.admin, role: admin }
- { scim: shield.admin, role: admin }
- { scim: shield.engineer, role: engineer }
Define Mappings – BOSH Admin for the BOSH and CF Tenant
It is also desired to have BOSH Admins control the backups for the BOSH Director database, the SHIELD database, and Cloud Foundry’s databases.
For non-SYSTEM tenants valid values for the role field are:
- admin – Full control over the tenant.
- engineer – Control over the configuration of stores, targets, retention policies, and jobs.
- operator – Control over running jobs, pausing and unpausing scheduled jobs, and performing restore operations.
In our case we want anyone who is a BOSH Admin to be a BOSH & CF Tenant Admin. To do this, define a SHIELD tenant and associate the BOSH Admins to be a SHIELD admin for this tenant:
auth:
- name: Prod BOSH UAA
properties:
mapping:
- tenant: BOSH and CF
rights:
- { scim: bosh.admin, role: admin }
Define Mappings – Postgres Admin
Now we can map the tenant for the Postgres Admin. The Postgres Admin is identified by the UAA group bosh.teams.postgres.admin
and we want this person to have complete control of their backups.
To do this define, a SHIELD tenant named Postgres Team
, and associate the UAA Group bosh.teams.postgres.admin
for the Postgres Admin with the SHIELD tenant role admin
for the Postgres Team tenant:
auth:
- name: Prod BOSH UAA
properties:
mapping:
- tenant: Postgres Team
rights:
- { scim: bosh.teams.postgres.admin, role: admin }
Define Mappings – RabbitMQ Admin
Now we can map the tenant for the RabbitMQ Admin. The RabbitMQ Admin is identified by the UAA group bosh.teams.rabbitmq.admin
and we want this person to have complete control of their backups.
To do this, define a SHIELD tenant named RabbitMQ Team
and associate the UAA Group bosh.teams.rabbitmq.admin
for the RabbitMQ Admin with the SHIELD tenant role admin
for the RabbitMQ Team tenant:
auth:
- name: Prod BOSH UAA
properties:
mapping:
- tenant: RabbitMQ Team
rights:
- { scim: bosh.teams.rabbitmq.admin, role: admin }
Define Mappings – Vault Admin
Now we can map the tenant for the Vault Admin. The Vault Admin is identified by the UAA group bosh.teams.vault.admin
, and we want this person to have complete control of their backups.
To do this define a SHIELD tenant named Vault Team
and associate the UAA Group bosh.teams.vault.admin
for the Vault Admin with the SHIELD tenant role admin
for the Vault Team tenant:
auth:
- name: Prod BOSH UAA
properties:
mapping:
- tenant: Vault Team
rights:
- scim: bosh.teams.vault.admin
role: admin
The Complete Mapping
The full snippet for the defining the UAA authentication provider and mappings is below. Members of the mapped UAA groups will be able to connect to the SHIELD tenants they are mapped to.
auth:
- name: Prod BOSH UAA
identifier: uaa1
backend: uaa
properties:
client_id: shield-dev
client_secret: s.h.i.e.l.d.
uaa_endpoint: https://192.168.50.6:8443
skip_verify_tls: true
mapping:
- tenant: SYSTEM
rights:
- { scim: bosh.admin, role: admin }
- { scim: shield.admin, role: admin }
- { scim: shield.engineer, role: engineer }
- tenant: BOSH and CF
rights:
- { scim: bosh.admin, role: admin }
- tenant: Postgres Team
rights:
- { scim: bosh.teams.postgres.admin, role: admin }
- tenant: RabbitMQ Team
rights:
- { scim: bosh.teams.rabbitmq.admin, role: admin }
- tenant: Vault Team
rights:
- { scim: bosh.teams.vault.admin, role: admin }
Selecting UAA Authentication Provider for Login
Once SHIELD is deployed with the configuration for the UAA this authentication provider will be available via the SHIELD UI. The authentication provider defined in auth.name
of the SHIELD manifest is what will appear on the login screen, clicking on this will start the UAA interaction:
Login to UAA
Now the interaction with UAA is initiated. Enter the username and password of one of the UAA user accounts that was defined in the manifest for BOSH. Note the URL in the browser navigates to the UAA instance on the BOSH Director as defined in auth.properties.uaa_endpoint
of the SHIELD manifest. In the screenshot below, we’ll login as BOSH Admin:
System Tenant & CF and BOSH Tenant
We are now logged in as the BOSH Admin. The BOSH Admin belongs to two SHIELD tenants: SYSTEM
and BOSH and CF
. Membership to SYSTEM gives the user access to the Admin
tab in the UI. Membership to the BOSH and CF
tenant allows the other Systems
, Storage
, and Retention
tabs to manage backups for BOSH, CF, and SHIELD database backups:
Postgres Tenant
If instead we had logged in as Postgres Admin we would have access to the Postgres Team
tenant but not access to other tenants or the Admin
tab:
Next Steps
Another supported SHIELD Authentication Provider is Github; it also has the concept of mapping. This involves mapping Github orgs to SHIELD tenants and roles. More about this is here.
You can also use a stand-alone deployment of UAA, or even the UAA instance that is included in Cloud Foundry. The example in this blog is based on a real world use case where there are BOSH Teams already leveraged to sandbox BOSH access. There are also tenant roles which were not used because each of the teams have a few people all with the same responsibilities to their teams. The additional tenant roles can be used for teams where team members have different roles and responsibilities.
Everyone deserves nice things, if there is another use case you would like to discuss, please contact us! There is a Slack channel #help
in shieldproject.slack.com or simply reply to this blog post.