Repository: chef/automate (go)

Issue:
LDAP login sometimes fails when there is a session for a user but no associated reference in refresh_token_table
## Describe the bug

> I have a customer running into issues with trying to login using LDAP with automate. It looks like it's accepting the credentials, but then giving an error "failed to delete refresh token: not found", then returns a 500 error to the browser. 

We've seen this bug pop up for at least four customers. The main commonality is that LDAP is configured.

While we don't understand why yet, it's apparently possible for a session to be created for an LDAP user whose user ID wasn't added to the `refresh_token table`. On subsequent logins, the user can't log in because it finds the session entry but no refresh_token entry.

## To Reproduce
We've so far been unable to reproduce the circumstances that caused the customer to not have an entry in the refresh_token table in dex.

However, you can simulate the state they're in by removing entries directly from the table.

```
chef-automate dev psql dex
delete from offline_session where user_id="some-user-id";
```

## Expected behavior
LDAP users with a session should always have an associated entry in the `refresh_token table`

We probably need some garbage collection. It'd be ideal to get a fix upstream in dex.

## Versions (please complete the following information):
- Automate Build Number: 
  CLI Build: 20200504210439
  Server Build: 20200506172513

## Additional context
- relevant dex code: https://github.com/dexidp/dex/blame/f2590ee07dbe6a9cd98179ea467255fab41466f4/server/handlers.go#L821-L834
- ticket: https://getchef.zendesk.com/agent/tickets/23553


Pull request:
auth: filter SAML groups
### :nut_and_bolt: Description: What code changed, and why?

We want to unblock SAML users with too many groups.

ℹ️ This branch includes #3615 and ~should rebased after that one is merged.~ **replaces it**

~🚧 Waiting for `core/dex` to be bumped to 2.24.0: https://github.com/habitat-sh/core-plans/pull/3366~ ✔️ 

~⚠️ **Needs docs** ⚠️~ 

### :chains: Related Resources

#3611
fixes #3668 

### :+1: Definition of Done

You can configure the list of groups, it'll be restricting the groups of users able to login using SAML.

### :athletic_shoe: How to Build and Test the Change

- `rebuild components/automate-dex`
- `rebuild components/automate-deployment`
- `rebuild components/automate-cli`

Login using SAML, note the logs:
```
[2020-05-11T09:51:40+00:00] authz-service.default(O): time="2020-05-11T09:51:40Z" level=info msg="Projects Authorized Query" action="event:events:list" projects="[]" resource="event:events" result="[]" subject="[team:saml:Everyone team:saml:devteam team:saml:All Developers user:saml:srenatus]"
```

Apply this config:
```
[dex.v1.sys.connectors.saml]
allowed_groups = ["Everyone"]
```

```
[16][default:/src:0]# chef-automate config patch saml_groups.toml

Updating deployment configuration

Applying deployment configuration
  Started automate-dex
Success: Configuration patched
```

and notice that **upon re-signin**, the list of user groups will be only `team:saml:Everyone`:

```
[2020-05-14T11:20:32+00:00] authz-service.default(O): time="2020-05-14T11:20:32Z" level=info msg="Projects Authorized Query" action="system:license:get" projects="[]" resource="system:status" result="[*]" subject="[team:saml:Everyone user:saml:srenatus]"
```

### :white_check_mark: Checklist

- [ ] I have read the [CONTRIBUTING document](https://github.com/chef/automate/blob/master/CONTRIBUTING.md).
- [X] Tests added/updated?
- [X] Docs added/updated?
- [X] All commits have been signed-off for the [Developer Certification of Origin](https://github.com/chef/chef/blob/master/CONTRIBUTING.md#developer-certification-of-origin-dco).

### :camera: Screenshots, if applicable


Patch:
diff --git a/api/config/dex/config_request.pb.go b/api/config/dex/config_request.pb.go
index 40c50a9a7..537f05ce7 100644
--- a/api/config/dex/config_request.pb.go
+++ b/api/config/dex/config_request.pb.go
@@ -953,6 +953,7 @@ type ConfigRequest_V1_Saml struct {
 	GroupsAttr           *wrappers.StringValue `protobuf:"bytes,5,opt,name=groups_attr,json=groupsAttr,proto3" json:"groups_attr,omitempty" toml:"groups_attr,omitempty" mapstructure:"groups_attr,omitempty"`
 	EntityIssuer         *wrappers.StringValue `protobuf:"bytes,6,opt,name=entity_issuer,json=entityIssuer,proto3" json:"entity_issuer,omitempty" toml:"entity_issuer,omitempty" mapstructure:"entity_issuer,omitempty"`
 	NameIdPolicyFormat   *wrappers.StringValue `protobuf:"bytes,7,opt,name=name_id_policy_format,json=nameIdPolicyFormat,proto3" json:"name_id_policy_format,omitempty" toml:"name_id_policy_format,omitempty" mapstructure:"name_id_policy_format,omitempty"`
+	AllowedGroups        []string              `protobuf:"bytes,8,rep,name=allowed_groups,json=allowedGroups,proto3" json:"allowed_groups,omitempty" toml:"allowed_groups,omitempty" mapstructure:"allowed_groups,omitempty"`
 	XXX_NoUnkeyedLiteral struct{}              `json:"-" toml:"-" mapstructure:"-,omitempty"`
 	XXX_unrecognized     []byte                `json:"-" toml:"-" mapstructure:"-,omitempty"`
 	XXX_sizecache        int32                 `json:"-" toml:"-" mapstructure:"-,omitempty"`
@@ -1032,6 +1033,13 @@ func (m *ConfigRequest_V1_Saml) GetNameIdPolicyFormat() *wrappers.StringValue {
 	return nil
 }
 
+func (m *ConfigRequest_V1_Saml) GetAllowedGroups() []string {
+	if m != nil {
+		return m.AllowedGroups
+	}
+	return nil
+}
+
 func init() {
 	proto.RegisterType((*ConfigRequest)(nil), "chef.automate.domain.dex.ConfigRequest")
 	proto.RegisterType((*ConfigRequest_V1)(nil), "chef.automate.domain.dex.ConfigRequest.V1")
@@ -1055,89 +1063,91 @@ func init() {
 }
 
 var fileDescriptor_3e591b6849cffa8a = []byte{
-	// 1341 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x98, 0xdd, 0x6e, 0x13, 0x47,
-	0x14, 0xc7, 0x95, 0xd8, 0xf1, 0xc7, 0x49, 0x42, 0xc2, 0x84, 0xc2, 0x6a, 0xa9, 0x10, 0x6a, 0xd5,
-	0x4f, 0x29, 0xeb, 0x26, 0x80, 0x54, 0x68, 0x69, 0x9b, 0x8f, 0x02, 0x09, 0xe1, 0x6b, 0x0d, 0xa8,
-	0xe2, 0x66, 0x35, 0xde, 0x1d, 0x6f, 0x56, 0x8c, 0x67, 0x36, 0x33, 0xe3, 0x10, 0xab, 0x52, 0xaf,
-	0xa0, 0x17, 0x7d, 0x8c, 0x3e, 0x43, 0xaf, 0x7a, 0xc9, 0x55, 0xef, 0xfa, 0x18, 0x7d, 0x00, 0x5e,
-	0xa0, 0x9a, 0x0f, 0x9b, 0x04, 0x07, 0xd8, 0x35, 0x5c, 0x72, 0x67, 0x67, 0xcf, 0xef, 0xef, 0x73,
-	0xe6, 0x9c, 0xf3, 0xdf, 0xcd, 0xc2, 0xa7, 0x38, 0xcf, 0x5a, 0x31, 0x67, 0xdd, 0x2c, 0x6d, 0x25,
-	0xe4, 0xc0, 0x7d, 0x8c, 0x04, 0xd9, 0xeb, 0x13, 0xa9, 0x82, 0x5c, 0x70, 0xc5, 0x91, 0x17, 0xef,
-	0x92, 0x6e, 0x80, 0xfb, 0x8a, 0xf7, 0xb0, 0x22, 0x41, 0xc2, 0x7b, 0x38, 0x63, 0x41, 0x42, 0x0e,
-	0xfc, 0x73, 0x87, 0x70, 0xb9, 0x8b, 0x05, 0x49, 0x5a, 0x29, 0xe5, 0x1d, 0x4c, 0x2d, 0xe9, 0x9f,
-	0x1d, 0xbf, 0xae, 0xa8, 0x74, 0x17, 0xb7, 0x63, 0xde, 0xcb, 0x39, 0x23, 0x4c, 0xc9, 0xd6, 0x50,
-	0x7c, 0x39, 0x15, 0x79, 0xdc, 0x32, 0xd7, 0xe3, 0xe5, 0x94, 0xb0, 0x65, 0xbc, 0xba, 0xec, 0x78,
-	0x2d, 0x85, 0x57, 0xf5, 0x97, 0x16, 0x66, 0x8c, 0x2b, 0xac, 0x32, 0xce, 0x86, 0x5a, 0xe7, 0x52,
-	0xce, 0x53, 0x4a, 0x2c, 0xd9, 0xe9, 0x77, 0x5b, 0x4f, 0x04, 0xce, 0x73, 0x22, 0xdc, 0xf5, 0x4f,
-	0xfe, 0xfc, 0x1c, 0xe6, 0x37, 0x8c, 0x4e, 0x68, 0x4b, 0x43, 0x57, 0x60, 0x7a, 0x7f, 0xc5, 0xab,
-	0x9c, 0x9f, 0xfa, 0x72, 0x76, 0xf5, 0xeb, 0xe0, 0x75, 0x15, 0x06, 0x47, 0xa0, 0xe0, 0xe1, 0x4a,
-	0x38, 0xbd, 0xbf, 0xe2, 0xff, 0xfd, 0x19, 0x4c, 0x3f, 0x5c, 0x41, 0x1b, 0x50, 0x91, 0x03, 0xe9,
-	0x4d, 0x19, 0x8d, 0x95, 0xe2, 0x1a, 0x41, 0x7b, 0x20, 0x15, 0xe9, 0x85, 0x9a, 0x46, 0x9b, 0x50,
-	0x91, 0xfb, 0xb1, 0x37, 0x6d, 0x44, 0x56, 0xcb, 0x88, 0x10, 0xb1, 0x9f, 0xc5, 0x24, 0xd4, 0xb8,
-	0xff, 0x5f, 0x0d, 0x6a, 0x56, 0x15, 0x5d, 0x84, 0x6a, 0x8f, 0x4a, 0xec, 0xd2, 0x3a, 0xff, 0x8a,
-	0x62, 0xc6, 0xba, 0x02, 0x07, 0xf6, 0x48, 0x83, 0x5b, 0x54, 0xe2, 0xd0, 0x44, 0xa3, 0x9f, 0xa0,
-	0x42, 0x79, 0xea, 0xd2, 0x08, 0x4a, 0xa4, 0xb1, 0xc3, 0xd3, 0x50, 0xa3, 0xa8, 0x0d, 0x75, 0x69,
-	0x53, 0x72, 0xa7, 0x7a, 0xb9, 0xf4, 0x89, 0x8c, 0x6a, 0x1a, 0x2a, 0xa1, 0x0d, 0xa8, 0xea, 0x89,
-	0xf0, 0xaa, 0x46, 0xb1, 0x55, 0x42, 0xf1, 0xba, 0xc8, 0xe3, 0xd0, 0xc0, 0x68, 0x07, 0xea, 0x52,
-	0x71, 0x81, 0x53, 0xe2, 0xcd, 0x94, 0x3f, 0x66, 0x4b, 0x86, 0x43, 0x09, 0xb4, 0x05, 0x35, 0x72,
-	0x90, 0x67, 0x62, 0xe0, 0xd5, 0x4a, 0x37, 0xfe, 0x67, 0x03, 0x86, 0x4e, 0x00, 0x85, 0xd0, 0xec,
-	0x70, 0xae, 0xa4, 0x12, 0x38, 0xf7, 0xea, 0x46, 0xed, 0x62, 0x09, 0xb5, 0xf5, 0x21, 0x1b, 0xbe,
-	0x94, 0x41, 0x0f, 0x00, 0x62, 0xce, 0x18, 0x89, 0x15, 0x17, 0xd2, 0x6b, 0x18, 0xd1, 0x4b, 0x25,
-	0x44, 0x37, 0x46, 0x70, 0x78, 0x48, 0x08, 0x7d, 0x0f, 0x15, 0x45, 0xa5, 0xd7, 0x3c, 0x76, 0x5f,
-	0x8e, 0x0c, 0xd5, 0xfd, 0x9d, 0xf6, 0x86, 0x20, 0x09, 0x61, 0x2a, 0xc3, 0x54, 0x86, 0x1a, 0xf3,
-	0xff, 0x99, 0x82, 0xba, 0xeb, 0x2d, 0xfa, 0x06, 0xaa, 0xbb, 0x5c, 0x2a, 0x37, 0x9f, 0x1f, 0x07,
-	0x76, 0x73, 0x83, 0xe1, 0xe6, 0x06, 0x6d, 0x25, 0x32, 0x96, 0x3e, 0xc4, 0xb4, 0x4f, 0x42, 0x13,
-	0x89, 0x6e, 0x40, 0x35, 0xe7, 0x42, 0xb9, 0xe1, 0x3c, 0x3b, 0x46, 0x6c, 0x31, 0x75, 0x61, 0xd5,
-	0x00, 0xeb, 0x67, 0x9e, 0xbf, 0xf0, 0x96, 0x46, 0x83, 0xb8, 0xf8, 0xf4, 0x8e, 0x3f, 0xb3, 0xab,
-	0x54, 0x2e, 0x43, 0xa3, 0x80, 0xd6, 0x60, 0x9e, 0x1c, 0x28, 0x22, 0x18, 0xa6, 0x51, 0x77, 0x2f,
-	0x61, 0x6e, 0x52, 0xdf, 0x9c, 0xc4, 0xdc, 0x10, 0xb9, 0xb6, 0x97, 0x30, 0xbf, 0x39, 0xaa, 0xc4,
-	0xbf, 0x0c, 0x95, 0x1d, 0x9e, 0xa2, 0x55, 0x98, 0xa1, 0x64, 0x9f, 0xd0, 0x42, 0x15, 0xd9, 0x50,
-	0xff, 0x57, 0xa8, 0xbb, 0xc1, 0x42, 0xdf, 0x42, 0x23, 0xc1, 0x0a, 0x77, 0xb0, 0x24, 0x85, 0x14,
-	0x46, 0xd1, 0xfa, 0x24, 0xfb, 0x92, 0x08, 0x77, 0x2e, 0x6f, 0x39, 0x49, 0x1d, 0xb9, 0x5d, 0x6d,
-	0x54, 0x16, 0x67, 0xfc, 0xdf, 0xa0, 0xaa, 0xb7, 0x63, 0x82, 0x4e, 0x6c, 0x16, 0xef, 0xc4, 0xd2,
-	0xf3, 0x17, 0xde, 0x82, 0xdd, 0xde, 0xc5, 0x67, 0x77, 0x7c, 0xf3, 0xc1, 0x76, 0xc1, 0x7f, 0x3a,
-	0x05, 0x35, 0xbb, 0x09, 0xe8, 0x47, 0x98, 0x93, 0x59, 0xca, 0x32, 0x96, 0x46, 0x8f, 0xc9, 0xc8,
-	0x4b, 0xdf, 0x9c, 0xca, 0xac, 0x23, 0x6e, 0x92, 0x81, 0x44, 0x97, 0xa1, 0x99, 0x25, 0x91, 0xe2,
-	0x8f, 0x09, 0x93, 0x85, 0x0e, 0xa2, 0x91, 0x25, 0xf7, 0x4d, 0xb4, 0x7f, 0x1b, 0x9a, 0xa3, 0x0d,
-	0x42, 0x6b, 0x70, 0x22, 0x63, 0x92, 0xc4, 0x7d, 0x41, 0x22, 0x9c, 0xf4, 0x32, 0xe6, 0x52, 0xf1,
-	0xc7, 0xc4, 0xd6, 0x39, 0xa7, 0x56, 0x6a, 0x7e, 0x48, 0xac, 0x69, 0xc0, 0xff, 0x6b, 0x1a, 0xe0,
-	0xe5, 0xf6, 0x68, 0x9f, 0xb0, 0xe8, 0x04, 0x37, 0x88, 0xeb, 0x06, 0x0c, 0x9d, 0x80, 0x76, 0x41,
-	0x9a, 0xe0, 0xdc, 0xd5, 0x57, 0xc6, 0x05, 0x77, 0x12, 0x9c, 0x87, 0x06, 0xd6, 0x22, 0x12, 0xf7,
-	0xa8, 0x1b, 0xf9, 0x32, 0x22, 0x6d, 0xdc, 0xa3, 0xa1, 0x81, 0xd1, 0x3d, 0x68, 0xf6, 0x24, 0x4e,
-	0x22, 0x93, 0x4e, 0xb5, 0xb4, 0x63, 0xdd, 0xd2, 0xac, 0xc9, 0xa9, 0xa1, 0x65, 0xf4, 0x27, 0xff,
-	0xf7, 0x29, 0xa8, 0xd9, 0x7a, 0x75, 0x33, 0x63, 0x9a, 0x11, 0xa6, 0xa2, 0x2c, 0x29, 0xb6, 0x0b,
-	0x36, 0x7c, 0x2b, 0xd1, 0x9b, 0xed, 0x50, 0x49, 0x62, 0x41, 0x54, 0xa1, 0x59, 0x98, 0xb3, 0x48,
-	0xdb, 0x10, 0xfe, 0xb3, 0x26, 0x54, 0x75, 0x46, 0xe8, 0x2a, 0xcc, 0xc6, 0x38, 0x8a, 0x39, 0x53,
-	0xfa, 0xd9, 0xa4, 0x50, 0x22, 0x10, 0xe3, 0x0d, 0x17, 0x3f, 0x5a, 0xab, 0xe9, 0xc2, 0x6b, 0x75,
-	0x09, 0xea, 0x9d, 0x8c, 0x25, 0x51, 0x41, 0x43, 0xaa, 0xe9, 0xe0, 0x4d, 0xa6, 0x6b, 0x36, 0x58,
-	0x8e, 0xa5, 0x7c, 0xc2, 0x45, 0xe2, 0x1a, 0xf2, 0x96, 0x9a, 0x35, 0x72, 0xd7, 0x11, 0xe8, 0x26,
-	0x2c, 0x69, 0x2b, 0x89, 0xb4, 0x3b, 0x44, 0x92, 0x60, 0x11, 0xef, 0xea, 0x2c, 0x66, 0x0a, 0x08,
-	0x2d, 0x6a, 0xf0, 0x81, 0x24, 0xa2, 0x6d, 0xb0, 0x4d, 0x86, 0x6e, 0xc0, 0x49, 0xa3, 0xb3, 0xd7,
-	0x27, 0x62, 0x10, 0x75, 0x33, 0xaa, 0x88, 0x70, 0x37, 0xc9, 0x37, 0x4b, 0x2d, 0x68, 0xec, 0x9e,
-	0xa6, 0xae, 0x19, 0x48, 0x57, 0xa6, 0xff, 0xc4, 0x70, 0x8f, 0x44, 0x58, 0x29, 0xe1, 0x6e, 0x8e,
-	0x6f, 0xa9, 0x6c, 0x88, 0xac, 0x29, 0x25, 0xd0, 0x0f, 0x60, 0xbe, 0x47, 0x59, 0x62, 0x15, 0x1a,
-	0x45, 0xba, 0xa8, 0x89, 0xad, 0xc4, 0xf0, 0xdf, 0x01, 0x90, 0x1e, 0xce, 0xa8, 0xa5, 0x9b, 0x05,
-	0xe8, 0xa6, 0x89, 0x37, 0xf0, 0x3d, 0x38, 0x6d, 0x7e, 0x3c, 0xc9, 0x64, 0x4e, 0xf1, 0x20, 0x7a,
-	0x59, 0x08, 0x14, 0x10, 0x5a, 0xd2, 0xec, 0xa6, 0x45, 0x6f, 0x0f, 0xeb, 0xb9, 0x05, 0xa7, 0x4c,
-	0xa7, 0x52, 0xc1, 0xfb, 0xf9, 0xa1, 0x56, 0xcd, 0x16, 0x10, 0x3c, 0xa9, 0xc9, 0xeb, 0x1a, 0x1c,
-	0xf5, 0x6a, 0x1b, 0x90, 0x55, 0x3a, 0xd2, 0xac, 0xb9, 0x22, 0x7d, 0x37, 0xdc, 0xe1, 0x6e, 0xfd,
-	0x02, 0xbe, 0xe5, 0x6d, 0x72, 0x32, 0xea, 0x0c, 0xec, 0x40, 0x99, 0x8a, 0xe7, 0x0b, 0x68, 0x9e,
-	0xb6, 0xbc, 0x49, 0x51, 0xae, 0x0f, 0xf4, 0x54, 0x99, 0xa2, 0x1f, 0xc1, 0xd9, 0xe3, 0x95, 0xf7,
-	0x35, 0xe6, 0x9d, 0x28, 0x20, 0x7d, 0x66, 0x5c, 0xda, 0x5c, 0x40, 0x6d, 0x38, 0x63, 0x4f, 0x60,
-	0xbc, 0x49, 0x0b, 0x05, 0x74, 0x4f, 0x19, 0xf8, 0xd5, 0x2e, 0xad, 0xc3, 0xc2, 0xe8, 0x36, 0xc2,
-	0x78, 0x24, 0x25, 0xf5, 0x16, 0x8b, 0xdf, 0x47, 0x6e, 0xf3, 0xb6, 0xa4, 0xfe, 0x1f, 0x4d, 0x68,
-	0x8e, 0x8c, 0xf2, 0x83, 0x19, 0x4d, 0x68, 0x46, 0xaf, 0xdb, 0x97, 0xda, 0x64, 0xfb, 0x72, 0xac,
-	0xb7, 0xd5, 0x27, 0xf1, 0xb6, 0xe3, 0x37, 0xaf, 0x31, 0xd1, 0xe6, 0x8d, 0xf9, 0x64, 0xf3, 0x9d,
-	0x7d, 0x12, 0xde, 0xc9, 0x27, 0x67, 0xdf, 0x97, 0x4f, 0xce, 0x4d, 0xea, 0x93, 0x1f, 0xcc, 0xe8,
-	0xbd, 0x9a, 0xd1, 0xbf, 0x15, 0xa8, 0xea, 0xe7, 0xbf, 0x77, 0xf5, 0xa1, 0x4b, 0x50, 0x97, 0x92,
-	0x47, 0x7d, 0x41, 0x0b, 0x59, 0x51, 0x4d, 0x4a, 0xfe, 0x40, 0xd0, 0x57, 0xa6, 0xab, 0x52, 0x6e,
-	0xba, 0xc6, 0xb6, 0xa3, 0x5a, 0x7a, 0x3b, 0xae, 0xc2, 0xac, 0x6b, 0xb6, 0x11, 0x28, 0x62, 0x45,
-	0x60, 0x81, 0x61, 0x06, 0xfa, 0xff, 0x60, 0x35, 0x88, 0x32, 0x29, 0xfb, 0x05, 0x9f, 0x86, 0xe6,
-	0x2c, 0xb2, 0x65, 0x08, 0x74, 0x07, 0x3e, 0x32, 0x05, 0x64, 0x49, 0x94, 0x73, 0x9a, 0xc5, 0x83,
-	0xa8, 0xcb, 0x45, 0x0f, 0xab, 0x42, 0xe6, 0x83, 0x34, 0xba, 0x95, 0xdc, 0x35, 0xe0, 0x35, 0xc3,
-	0x5d, 0x41, 0xcf, 0x5f, 0x78, 0x27, 0x60, 0x6e, 0xf4, 0xc6, 0x2d, 0x21, 0x07, 0xdb, 0xd5, 0xc6,
-	0xd4, 0x62, 0x65, 0xfd, 0xab, 0x47, 0x5f, 0xa4, 0x99, 0xda, 0xed, 0x77, 0x82, 0x98, 0xf7, 0x5a,
-	0xfa, 0xa9, 0x7e, 0xf4, 0x5e, 0xae, 0x75, 0xf4, 0x3d, 0x61, 0xa7, 0x66, 0x7e, 0xee, 0xc2, 0xff,
-	0x01, 0x00, 0x00, 0xff, 0xff, 0xdd, 0x68, 0xa0, 0xca, 0x40, 0x14, 0x00, 0x00,
+	// 1361 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x98, 0x5b, 0x6f, 0x13, 0x47,
+	0x14, 0xc7, 0x95, 0xd8, 0xf1, 0xe5, 0xc4, 0xb9, 0x30, 0xa1, 0xb0, 0x5a, 0x2a, 0x84, 0x5a, 0xd1,
+	0xd2, 0x4a, 0x59, 0x37, 0x01, 0xa4, 0x42, 0x4b, 0xdb, 0x5c, 0x0a, 0x24, 0x84, 0xdb, 0x1a, 0x50,
+	0xc5, 0xcb, 0x6a, 0xbc, 0x3b, 0xde, 0xac, 0x18, 0xcf, 0x6c, 0x66, 0xc6, 0x21, 0x56, 0xa5, 0x3e,
+	0x41, 0x1f, 0xfa, 0x79, 0xfa, 0x09, 0x78, 0x6a, 0x3f, 0x46, 0x9f, 0xfa, 0x01, 0x90, 0xfa, 0x5c,
+	0xcd, 0xc5, 0x26, 0xc1, 0x01, 0xd6, 0x86, 0x47, 0xde, 0x6c, 0xef, 0xf9, 0xfd, 0x73, 0xce, 0x9c,
+	0x73, 0xfe, 0xbb, 0x59, 0xf8, 0x1c, 0xe7, 0x59, 0x33, 0xe6, 0xac, 0x93, 0xa5, 0xcd, 0x84, 0x1c,
+	0xb8, 0x8f, 0x91, 0x20, 0x7b, 0x3d, 0x22, 0x55, 0x90, 0x0b, 0xae, 0x38, 0xf2, 0xe2, 0x5d, 0xd2,
+	0x09, 0x70, 0x4f, 0xf1, 0x2e, 0x56, 0x24, 0x48, 0x78, 0x17, 0x67, 0x2c, 0x48, 0xc8, 0x81, 0x7f,
+	0xf6, 0x10, 0x2e, 0x77, 0xb1, 0x20, 0x49, 0x33, 0xa5, 0xbc, 0x8d, 0xa9, 0x25, 0xfd, 0x33, 0xa3,
+	0xd7, 0x15, 0x95, 0xee, 0xe2, 0x76, 0xcc, 0xbb, 0x39, 0x67, 0x84, 0x29, 0xd9, 0x1c, 0x88, 0x2f,
+	0xa7, 0x22, 0x8f, 0x9b, 0xe6, 0x7a, 0xbc, 0x9c, 0x12, 0xb6, 0x8c, 0x57, 0x97, 0x1d, 0xaf, 0xa5,
+	0xf0, 0xaa, 0xfe, 0xd2, 0xc4, 0x8c, 0x71, 0x85, 0x55, 0xc6, 0xd9, 0x40, 0xeb, 0x6c, 0xca, 0x79,
+	0x4a, 0x89, 0x25, 0xdb, 0xbd, 0x4e, 0xf3, 0xa9, 0xc0, 0x79, 0x4e, 0x84, 0xbb, 0xfe, 0xd9, 0xdf,
+	0x5f, 0xc0, 0xdc, 0x86, 0xd1, 0x09, 0x6d, 0x69, 0xe8, 0x2a, 0x4c, 0xef, 0xaf, 0x78, 0xa5, 0x73,
+	0x53, 0x17, 0x66, 0x57, 0xbf, 0x0e, 0xde, 0x54, 0x61, 0x70, 0x04, 0x0a, 0x1e, 0xad, 0x84, 0xd3,
+	0xfb, 0x2b, 0xfe, 0x3f, 0xe7, 0x61, 0xfa, 0xd1, 0x0a, 0xda, 0x80, 0x92, 0xec, 0x4b, 0x6f, 0xca,
+	0x68, 0xac, 0x14, 0xd7, 0x08, 0x5a, 0x7d, 0xa9, 0x48, 0x37, 0xd4, 0x34, 0xda, 0x84, 0x92, 0xdc,
+	0x8f, 0xbd, 0x69, 0x23, 0xb2, 0x3a, 0x8e, 0x08, 0x11, 0xfb, 0x59, 0x4c, 0x42, 0x8d, 0xfb, 0xff,
+	0x56, 0xa0, 0x62, 0x55, 0xd1, 0x25, 0x28, 0x77, 0xa9, 0xc4, 0x2e, 0xad, 0x73, 0xaf, 0x29, 0x66,
+	0xac, 0x23, 0x70, 0x60, 0x8f, 0x34, 0xb8, 0x4d, 0x25, 0x0e, 0x4d, 0x34, 0xfa, 0x09, 0x4a, 0x94,
+	0xa7, 0x2e, 0x8d, 0x60, 0x8c, 0x34, 0x76, 0x78, 0x1a, 0x6a, 0x14, 0xb5, 0xa0, 0x2a, 0x6d, 0x4a,
+	0xee, 0x54, 0xaf, 0x8c, 0x7d, 0x22, 0xc3, 0x9a, 0x06, 0x4a, 0x68, 0x03, 0xca, 0x7a, 0x22, 0xbc,
+	0xb2, 0x51, 0x6c, 0x8e, 0xa1, 0x78, 0x43, 0xe4, 0x71, 0x68, 0x60, 0xb4, 0x03, 0x55, 0xa9, 0xb8,
+	0xc0, 0x29, 0xf1, 0x66, 0xc6, 0x3f, 0x66, 0x4b, 0x86, 0x03, 0x09, 0xb4, 0x05, 0x15, 0x72, 0x90,
+	0x67, 0xa2, 0xef, 0x55, 0xc6, 0x6e, 0xfc, 0xcf, 0x06, 0x0c, 0x9d, 0x00, 0x0a, 0xa1, 0xde, 0xe6,
+	0x5c, 0x49, 0x25, 0x70, 0xee, 0x55, 0x8d, 0xda, 0xa5, 0x31, 0xd4, 0xd6, 0x07, 0x6c, 0xf8, 0x4a,
+	0x06, 0x3d, 0x04, 0x88, 0x39, 0x63, 0x24, 0x56, 0x5c, 0x48, 0xaf, 0x66, 0x44, 0x2f, 0x8f, 0x21,
+	0xba, 0x31, 0x84, 0xc3, 0x43, 0x42, 0xe8, 0x7b, 0x28, 0x29, 0x2a, 0xbd, 0xfa, 0xb1, 0xfb, 0x72,
+	0x64, 0xa8, 0x1e, 0xec, 0xb4, 0x36, 0x04, 0x49, 0x08, 0x53, 0x19, 0xa6, 0x32, 0xd4, 0x98, 0xff,
+	0xd7, 0x14, 0x54, 0x5d, 0x6f, 0xd1, 0x37, 0x50, 0xde, 0xe5, 0x52, 0xb9, 0xf9, 0xfc, 0x34, 0xb0,
+	0x9b, 0x1b, 0x0c, 0x36, 0x37, 0x68, 0x29, 0x91, 0xb1, 0xf4, 0x11, 0xa6, 0x3d, 0x12, 0x9a, 0x48,
+	0x74, 0x13, 0xca, 0x39, 0x17, 0xca, 0x0d, 0xe7, 0x99, 0x11, 0x62, 0x8b, 0xa9, 0x8b, 0xab, 0x06,
+	0x58, 0x3f, 0xfd, 0xe2, 0xa5, 0xb7, 0x34, 0x1c, 0xc4, 0xc5, 0x67, 0x77, 0xfd, 0x99, 0x5d, 0xa5,
+	0x72, 0x19, 0x1a, 0x05, 0xb4, 0x06, 0x73, 0xe4, 0x40, 0x11, 0xc1, 0x30, 0x8d, 0x3a, 0x7b, 0x09,
+	0x73, 0x93, 0xfa, 0xf6, 0x24, 0x1a, 0x03, 0xe4, 0xfa, 0x5e, 0xc2, 0xfc, 0xfa, 0xb0, 0x12, 0xff,
+	0x0a, 0x94, 0x76, 0x78, 0x8a, 0x56, 0x61, 0x86, 0x92, 0x7d, 0x42, 0x0b, 0x55, 0x64, 0x43, 0xfd,
+	0x5f, 0xa1, 0xea, 0x06, 0x0b, 0x7d, 0x0b, 0xb5, 0x04, 0x2b, 0xdc, 0xc6, 0x92, 0x14, 0x52, 0x18,
+	0x46, 0xeb, 0x93, 0xec, 0x49, 0x22, 0xdc, 0xb9, 0xbc, 0xe3, 0x24, 0x75, 0xe4, 0x76, 0xb9, 0x56,
+	0x5a, 0x9c, 0xf1, 0x7f, 0x83, 0xb2, 0xde, 0x8e, 0x09, 0x3a, 0xb1, 0x59, 0xbc, 0x13, 0x4b, 0x2f,
+	0x5e, 0x7a, 0x0b, 0x76, 0x7b, 0x17, 0x9f, 0xdf, 0xf5, 0xcd, 0x07, 0xdb, 0x05, 0xff, 0xd9, 0x14,
+	0x54, 0xec, 0x26, 0xa0, 0x1f, 0xa1, 0x21, 0xb3, 0x94, 0x65, 0x2c, 0x8d, 0x9e, 0x90, 0xa1, 0x97,
+	0xbe, 0x3d, 0x95, 0x59, 0x47, 0xdc, 0x22, 0x7d, 0x89, 0xae, 0x40, 0x3d, 0x4b, 0x22, 0xc5, 0x9f,
+	0x10, 0x26, 0x0b, 0x1d, 0x44, 0x2d, 0x4b, 0x1e, 0x98, 0x68, 0xff, 0x0e, 0xd4, 0x87, 0x1b, 0x84,
+	0xd6, 0x60, 0x3e, 0x63, 0x92, 0xc4, 0x3d, 0x41, 0x22, 0x9c, 0x74, 0x33, 0xe6, 0x52, 0xf1, 0x47,
+	0xc4, 0xd6, 0x39, 0xa7, 0x56, 0x6a, 0x6e, 0x40, 0xac, 0x69, 0xc0, 0xff, 0x73, 0x1a, 0xe0, 0xd5,
+	0xf6, 0x68, 0x9f, 0xb0, 0xe8, 0x04, 0x37, 0x88, 0x1b, 0x06, 0x0c, 0x9d, 0x80, 0x76, 0x41, 0x9a,
+	0xe0, 0xdc, 0xd5, 0x37, 0x8e, 0x0b, 0xee, 0x24, 0x38, 0x0f, 0x0d, 0xac, 0x45, 0x24, 0xee, 0x52,
+	0x37, 0xf2, 0xe3, 0x88, 0xb4, 0x70, 0x97, 0x86, 0x06, 0x46, 0xf7, 0xa1, 0xde, 0x95, 0x38, 0x89,
+	0x4c, 0x3a, 0xe5, 0xb1, 0x1d, 0xeb, 0xb6, 0x66, 0x4d, 0x4e, 0x35, 0x2d, 0xa3, 0x3f, 0xf9, 0xbf,
+	0x4f, 0x41, 0xc5, 0xd6, 0xab, 0x9b, 0x19, 0xd3, 0x8c, 0x30, 0x15, 0x65, 0x49, 0xb1, 0x5d, 0xb0,
+	0xe1, 0x5b, 0x89, 0xde, 0x6c, 0x87, 0x4a, 0x12, 0x0b, 0xa2, 0x0a, 0xcd, 0x42, 0xc3, 0x22, 0x2d,
+	0x43, 0xf8, 0xcf, 0xeb, 0x50, 0xd6, 0x19, 0xa1, 0x6b, 0x30, 0x1b, 0xe3, 0x28, 0xe6, 0x4c, 0xe9,
+	0x67, 0x93, 0x42, 0x89, 0x40, 0x8c, 0x37, 0x5c, 0xfc, 0x70, 0xad, 0xa6, 0x0b, 0xaf, 0xd5, 0x65,
+	0xa8, 0xb6, 0x33, 0x96, 0x44, 0x05, 0x0d, 0xa9, 0xa2, 0x83, 0x37, 0x99, 0xae, 0xd9, 0x60, 0x39,
+	0x96, 0xf2, 0x29, 0x17, 0x89, 0x6b, 0xc8, 0x3b, 0x6a, 0xd6, 0xc8, 0x3d, 0x47, 0xa0, 0x5b, 0xb0,
+	0xa4, 0xad, 0x24, 0xd2, 0xee, 0x10, 0x49, 0x82, 0x45, 0xbc, 0xab, 0xb3, 0x98, 0x29, 0x20, 0xb4,
+	0xa8, 0xc1, 0x87, 0x92, 0x88, 0x96, 0xc1, 0x36, 0x19, 0xba, 0x09, 0x27, 0x8c, 0xce, 0x5e, 0x8f,
+	0x88, 0x7e, 0xd4, 0xc9, 0xa8, 0x22, 0xc2, 0xdd, 0x24, 0xdf, 0x2e, 0xb5, 0xa0, 0xb1, 0xfb, 0x9a,
+	0xba, 0x6e, 0x20, 0x5d, 0x99, 0xfe, 0x89, 0xe1, 0x2e, 0x89, 0xb0, 0x52, 0xc2, 0xdd, 0x1c, 0xdf,
+	0x51, 0xd9, 0x00, 0x59, 0x53, 0x4a, 0xa0, 0x1f, 0xc0, 0x7c, 0x8f, 0xb2, 0xc4, 0x2a, 0xd4, 0x8a,
+	0x74, 0x51, 0x13, 0x5b, 0x89, 0xe1, 0xbf, 0x03, 0x20, 0x5d, 0x9c, 0x51, 0x4b, 0xd7, 0x0b, 0xd0,
+	0x75, 0x13, 0x6f, 0xe0, 0xfb, 0x70, 0xca, 0xfc, 0xf1, 0x24, 0x93, 0x39, 0xc5, 0xfd, 0xe8, 0x55,
+	0x21, 0x50, 0x40, 0x68, 0x49, 0xb3, 0x9b, 0x16, 0xbd, 0x33, 0xa8, 0xe7, 0x36, 0x9c, 0x34, 0x9d,
+	0x4a, 0x05, 0xef, 0xe5, 0x87, 0x5a, 0x35, 0x5b, 0x40, 0xf0, 0x84, 0x26, 0x6f, 0x68, 0x70, 0xd8,
+	0xab, 0x6d, 0x40, 0x56, 0xe9, 0x48, 0xb3, 0x1a, 0x45, 0xfa, 0x6e, 0xb8, 0xc3, 0xdd, 0xfa, 0x05,
+	0x7c, 0xcb, 0xdb, 0xe4, 0x64, 0xd4, 0xee, 0xdb, 0x81, 0x32, 0x15, 0xcf, 0x15, 0xd0, 0x3c, 0x65,
+	0x79, 0x93, 0xa2, 0x5c, 0xef, 0xeb, 0xa9, 0x32, 0x45, 0x3f, 0x86, 0x33, 0xc7, 0x2b, 0xef, 0x6b,
+	0xcc, 0x9b, 0x2f, 0x20, 0x7d, 0x7a, 0x54, 0xda, 0x5c, 0x40, 0x2d, 0x38, 0x6d, 0x4f, 0x60, 0xb4,
+	0x49, 0x0b, 0x05, 0x74, 0x4f, 0x1a, 0xf8, 0xf5, 0x2e, 0xad, 0xc3, 0xc2, 0xf0, 0x36, 0xc2, 0x78,
+	0x24, 0x25, 0xf5, 0x16, 0x8b, 0xdf, 0x47, 0xee, 0xf0, 0x96, 0xa4, 0xfe, 0x1f, 0x75, 0xa8, 0x0f,
+	0x8d, 0xf2, 0xa3, 0x19, 0x4d, 0x68, 0x46, 0x6f, 0xda, 0x97, 0xca, 0x64, 0xfb, 0x72, 0xac, 0xb7,
+	0x55, 0x27, 0xf1, 0xb6, 0xe3, 0x37, 0xaf, 0x36, 0xd1, 0xe6, 0x8d, 0xf8, 0x64, 0xfd, 0xbd, 0x7d,
+	0x12, 0xde, 0xcb, 0x27, 0x67, 0x3f, 0x94, 0x4f, 0x36, 0x26, 0xf5, 0xc9, 0x8f, 0x66, 0xf4, 0x41,
+	0xcd, 0xe8, 0xbf, 0x12, 0x94, 0xf5, 0xf3, 0xdf, 0xfb, 0xfa, 0xd0, 0x65, 0xa8, 0x4a, 0xc9, 0xa3,
+	0x9e, 0xa0, 0x85, 0xac, 0xa8, 0x22, 0x25, 0x7f, 0x28, 0xe8, 0x6b, 0xd3, 0x55, 0x1a, 0x6f, 0xba,
+	0x46, 0xb6, 0xa3, 0x3c, 0xf6, 0x76, 0x5c, 0x83, 0x59, 0xd7, 0x6c, 0x23, 0x50, 0xc4, 0x8a, 0xc0,
+	0x02, 0x83, 0x0c, 0xf4, 0xff, 0xc1, 0xaa, 0x1f, 0x65, 0x52, 0xf6, 0x0a, 0x3e, 0x0d, 0x35, 0x2c,
+	0xb2, 0x65, 0x08, 0x74, 0x17, 0x3e, 0x31, 0x05, 0x64, 0x49, 0x94, 0x73, 0x9a, 0xc5, 0xfd, 0xa8,
+	0xc3, 0x45, 0x17, 0xab, 0x42, 0xe6, 0x83, 0x34, 0xba, 0x95, 0xdc, 0x33, 0xe0, 0x75, 0xc3, 0xa1,
+	0xf3, 0x30, 0x8f, 0x29, 0xe5, 0x4f, 0x49, 0xe2, 0xe6, 0xd8, 0xab, 0x9d, 0x2b, 0x5d, 0xa8, 0x87,
+	0x73, 0xee, 0x57, 0x3b, 0x9c, 0x57, 0xd1, 0x8b, 0x97, 0xde, 0x3c, 0x34, 0x86, 0x2f, 0xe6, 0x12,
+	0x72, 0xb0, 0x5d, 0xae, 0x4d, 0x2d, 0x96, 0xd6, 0xbf, 0x7a, 0xfc, 0x65, 0x9a, 0xa9, 0xdd, 0x5e,
+	0x3b, 0x88, 0x79, 0xb7, 0xa9, 0x1f, 0xfe, 0x87, 0xaf, 0xef, 0x9a, 0x47, 0x5f, 0x27, 0xb6, 0x2b,
+	0x26, 0xab, 0x8b, 0xff, 0x07, 0x00, 0x00, 0xff, 0xff, 0x94, 0x03, 0x11, 0xbc, 0x67, 0x14, 0x00,
+	0x00,
 }
diff --git a/api/config/dex/config_request.proto b/api/config/dex/config_request.proto
index 70132badb..511381445 100644
--- a/api/config/dex/config_request.proto
+++ b/api/config/dex/config_request.proto
@@ -123,6 +123,7 @@ message ConfigRequest {
 			google.protobuf.StringValue groups_attr = 5;
 			google.protobuf.StringValue entity_issuer = 6;
 			google.protobuf.StringValue name_id_policy_format = 7;
+			repeated string allowed_groups = 8;
 		}
 	}
 }
diff --git a/components/automate-chef-io/content/docs/saml.md b/components/automate-chef-io/content/docs/saml.md
index 1723b754c..4da52744b 100644
--- a/components/automate-chef-io/content/docs/saml.md
+++ b/components/automate-chef-io/content/docs/saml.md
@@ -59,6 +59,7 @@ sso_url = "<your SSO URL>"                  # required
 email_attr = "<your email attribute>"       # required
 username_attr = "<your username attribute>" # required
 groups_attr = "<your groups attribute>"     # optional
+allowed_groups = ["group1", "group 2"]      # optional
 entity_issuer = "<your entity issuer>"      # optional
 name_id_policy_format = "<see below>"       # optional
 ```
@@ -78,10 +79,13 @@ k2WFcoiiKyeIznNScx/K6AeykKR/lPrJedanSA==
 ```
 
 {{% warning %}}
-The `groups_attr` setting is optional. However, if it is not provided,
-users authenticating via SAML will not be members of any teams.
+The `groups_attr` setting is optional, but if not provided, users authenticating via SAML will not be members of any teams.
 {{% /warning %}}
 
+Setting `allowed_groups` provides SAML sign in to members of the listed groups.
+All of the other user groups that are _not_ in the list are discarded, and not available to Chef Automate.
+In the configuration example above, only users in either "group1" or "group2" may sign in, and those groups would appear as `team:saml:group1` and `team:saml:group2` respectively.
+
 Chef Automate supports using SAML to authenticate users and apply permissions to SAML groups. See [IAM Overview]({{< relref "iam-v2-overview.md" >}}).
 
 ```toml
diff --git a/components/automate-dex/habitat/plan.sh b/components/automate-dex/habitat/plan.sh
index f7711806d..d3a9f493f 100644
--- a/components/automate-dex/habitat/plan.sh
+++ b/components/automate-dex/habitat/plan.sh
@@ -16,7 +16,7 @@ pkg_binds=(
   [pg-sidecar-service]="port"
 )
 pkg_deps=(
-  core/dex/2.19.0
+  core/dex/2.24.0
   chef/mlsa
   ${local_platform_tools_origin:-chef}/automate-platform-tools
   core/bash
diff --git a/components/automate-dex/habitat/templates/config.yml b/components/automate-dex/habitat/templates/config.yml
index f29edd636..0ff68aa37 100644
--- a/components/automate-dex/habitat/templates/config.yml
+++ b/components/automate-dex/habitat/templates/config.yml
@@ -211,6 +211,13 @@ connectors:
       usernameAttr: {{cfg.connectors.saml.username_attr}}
       emailAttr: {{cfg.connectors.saml.email_attr}}
       groupsAttr: {{cfg.connectors.saml.groups_attr}}
+      {{- if cfg.connectors.saml.allowed_groups}}
+      allowedGroups:
+        {{- range cfg.connectors.saml.allowed_groups}}
+        - {{.}}
+        {{- end}}
+      filterGroups: true
+      {{- end}}
       nameIDPolicyFormat: {{cfg.connectors.saml.name_id_policy_format}}
   {{- end}}
 {{- end}}
diff --git a/components/automate-dex/web/templates/login.html b/components/automate-dex/web/templates/login.html
index e81e70566..139d5d4b3 100644
--- a/components/automate-dex/web/templates/login.html
+++ b/components/automate-dex/web/templates/login.html
@@ -7,12 +7,12 @@
     <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
     <title>{{ issuer }}</title>
     <meta name="viewport" content="width=device-width, initial-scale=1.0">
-    <link href="{{ url "static/main.css" }}" rel="stylesheet">
-    <link href="{{ url "theme/styles.css" }}" rel="stylesheet">
+    <link href="{{ url .ReqPath "static/main.css" }}" rel="stylesheet">
+    <link href="{{ url .ReqPath "theme/styles.css" }}" rel="stylesheet">
   </head>
   <div class="theme-panel">
     <div class="logo">
-      <img class="theme-navbar__logo" src="{{url "static/img/automate-blue-d9789f4b.svg" }}">
+      <img class="theme-navbar__logo" src="{{url .ReqPath "static/img/automate-blue-d9789f4b.svg" }}">
     </div>
     <div>
       {{ range $c := .Connectors }}
diff --git a/components/automate-dex/web/templates/password.html b/components/automate-dex/web/templates/password.html
index dccae35fe..5424dad85 100644
--- a/components/automate-dex/web/templates/password.html
+++ b/components/automate-dex/web/templates/password.html
@@ -7,9 +7,9 @@
     <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
     <title>{{ issuer }}</title>
     <meta name="viewport" content="width=device-width, initial-scale=1.0">
-    <link href="{{ url "static/main.css" }}" rel="stylesheet">
-    <link href="{{ url "theme/styles.css" }}" rel="stylesheet">
-    <link rel="stylesheet" href="{{ url "static/font-awesome-4.7.0/css/font-awesome.min.css" }}">
+    <link href="{{ url .ReqPath "static/main.css" }}" rel="stylesheet">
+    <link href="{{ url .ReqPath "theme/styles.css" }}" rel="stylesheet">
+    <link rel="stylesheet" href="{{ url .ReqPath "static/font-awesome-4.7.0/css/font-awesome.min.css" }}">
   </head>
   {{ if .BackLink }}
   <a class="back" href="javascript:history.back()">
@@ -21,7 +21,7 @@
   {{ end }}
   <div class="theme-panel">
     <div class="logo">
-      <img class="theme-navbar__logo" src="{{url "static/img/automate-blue-d9789f4b.svg" }}">
+      <img class="theme-navbar__logo" src="{{url .ReqPath "static/img/automate-blue-d9789f4b.svg" }}">
     </div>
     {{ if .Invalid }}
     <div class="dex-error-box">


Test patch:
diff --git a/api/config/dex/config_request_test.go b/api/config/dex/config_request_test.go
index 3962a31ff..261ec40c8 100644
--- a/api/config/dex/config_request_test.go
+++ b/api/config/dex/config_request_test.go
@@ -53,6 +53,7 @@ func TestValidate(t *testing.T) {
 			UsernameAttr:       w.String("username"),
 			GroupsAttr:         w.String("groups"),
 			NameIdPolicyFormat: w.String("urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"),
+			AllowedGroups:      []string{"admins", "ops"},
 		}
 	}
 
@@ -369,6 +370,23 @@ func TestValidate(t *testing.T) {
 		})
 	})
 
+	t.Run("allowed_groups (saml)", func(t *testing.T) {
+		valid := map[string][]string{
+			"one group":  {"admins"},
+			"two groups": {"admins", "ops"},
+			"no groups":  {}, // should this warn?
+		}
+		for k, v := range valid {
+			t.Run(k, func(t *testing.T) {
+				cfg := dex.DefaultConfigRequest()
+				saml := completeSAML()
+				saml.AllowedGroups = v
+				cfg.V1.Sys.Connectors = &dex.ConfigRequest_V1_Connectors{Saml: saml}
+				assert.NoError(t, cfg.Validate())
+			})
+		}
+	})
+
 	t.Run("ca_contents", func(t *testing.T) {
 		tests := map[string]func(certs string) *dex.ConfigRequest_V1_Connectors{
 			"saml": func(certs string) *dex.ConfigRequest_V1_Connectors {
diff --git a/api/config/shared/config_test.go b/api/config/shared/config_test.go
index 9ab5ac3dd..ab33e4e6c 100644
--- a/api/config/shared/config_test.go
+++ b/api/config/shared/config_test.go
@@ -1,21 +1,60 @@
-package shared
+package shared_test
 
 import (
 	"testing"
 
+	"github.com/chef/automate/api/config/dex"
+	"github.com/chef/automate/api/config/shared"
+	"github.com/chef/toml"
 	"github.com/stretchr/testify/assert"
 )
 
 func TestAddKeyMissing(t *testing.T) {
-	c := NewInvalidConfigError()
+	c := shared.NewInvalidConfigError()
 	c.AddMissingKey("foo")
 
 	assert.EqualValues(t, c.MissingKeys(), []string{"foo"})
 }
 
 func TestAddInvalidValue(t *testing.T) {
-	c := NewInvalidConfigError()
+	c := shared.NewInvalidConfigError()
 	c.AddInvalidValue("foo", "bar")
 
 	assert.EqualValues(t, c.InvalidValues(), map[string]string{"foo": "bar"})
 }
+
+func TestDexSAMLAllowedGroupsOptionalList(t *testing.T) {
+	t.Run("no list", func(t *testing.T) {
+		c := loadDexSAMLConfigFromToml(`
+groups_attr = "groups"
+`)
+		setting := c.GetAllowedGroups()
+		assert.Equal(t, "groups", c.GetGroupsAttr().Value)
+		assert.Equal(t, []string(nil), setting) // not set means nil
+	})
+
+	t.Run("empty list", func(t *testing.T) {
+		c := loadDexSAMLConfigFromToml(`
+allowed_groups = []
+`)
+		setting := c.GetAllowedGroups()
+		assert.EqualValues(t, []string{}, setting) // set to empty list means []string{}
+	})
+
+	t.Run("non-empty list", func(t *testing.T) {
+		c := loadDexSAMLConfigFromToml(`
+allowed_groups = ["alices", "bobs"]
+`)
+		setting := c.GetAllowedGroups()
+		assert.EqualValues(t, []string{"alices", "bobs"}, setting)
+	})
+}
+
+func loadDexSAMLConfigFromToml(s string) *dex.ConfigRequest_V1_Saml {
+	c := &dex.ConfigRequest_V1_Saml{}
+	err := toml.Unmarshal([]byte(s), c)
+	if err != nil {
+		panic(err)
+	}
+	return c
+}