Skip to content

Commit f5a7480

Browse files
committed
Add DEP 2876
1 parent 6b3ed9a commit f5a7480

File tree

1 file changed

+120
-0
lines changed

1 file changed

+120
-0
lines changed
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
# Dex Enhancement Proposal (DEP) 2876 - 2023-05-17 - Extend payload
2+
3+
## Table of Contents
4+
5+
- [Summary](#summary)
6+
- [Motivation](#motivation)
7+
- [Goals/Pain](#goals)
8+
- [Non-Goals](#non-goals)
9+
- [Proposal](#proposal)
10+
- [User Experience](#user-experience)
11+
- [Implementation Details/Notes/Constraints](#implementation-detailsnotesconstraints)
12+
- [Risks and Mitigations](#risks-and-mitigations)
13+
- [Alternatives](#alternatives)
14+
- [Future Improvements](#future-improvements)
15+
16+
## Summary
17+
18+
Dex has very rigid claims support. Adding additional claims via a connector requires forking the code and making changes to various internal structures. There are a number of proposals where this discussed, namely #1635 .
19+
The scope of these is fairly large and we are exploring a possible solution that limits itself to just
20+
mutating of the claims.
21+
22+
## Context
23+
24+
- #1636
25+
26+
## Motivation
27+
28+
### Goals
29+
30+
The working goals of this proposal are:
31+
32+
- Minimal changes to Dex core source
33+
- Provide an optional Go Interface specification connectors can implement to support extending token payload
34+
- Limit the interface to a sing method which allows mutating all claims before Dex core signs and delivers it
35+
36+
### Non-goals
37+
38+
- We will not explore dynamic loading. This is a future topic.
39+
40+
## Proposal
41+
42+
### User Experience
43+
44+
The implementation is fully backwards compatible. Users not requiring this
45+
feature won't have to change anything in their Dex deployment.
46+
47+
We expect that connectors will expose additional configuration options to allow for customizations
48+
of the payload extender functionality. Examples are toggles to include/exclude certain IDP claims
49+
50+
### Implementation Details/Notes/Constraints
51+
52+
We propose adding a new PayloadExtender interface which connectors can choose to implement:
53+
54+
```golang
55+
// PayloadExtender allows connectors to enhance the payload before signing
56+
type PayloadExtender interface {
57+
ExtendPayload(scopes []string, payload []byte, connectorData []byte) ([]byte, error)
58+
}
59+
```
60+
61+
The `ExtendPayload` method will be called just before the `JWT` is signed by Dex core.
62+
63+
By implementing this interface connectors get a chance to mutate the `id_token` payload
64+
before signature creation. The `scopes` may be used to perform conditional mutation.
65+
The `payload` is passed as a byte array as well as the `connectorData` associated with the authorization request. This allows the connector to pass session specific context via `connectorData`.
66+
The resulting mutated structure is returned including an `error` condition.
67+
68+
> A separate DEP will be created to propopse `Dynamic Scopes support` so payload extending can be application driven.
69+
70+
### Working example
71+
72+
A working example of this interface implementation could look like this:
73+
74+
```golang
75+
func (c *hsdpConnector) ExtendPayload(scopes []string, payload []byte, cdata []byte) ([]byte, error) {
76+
var cd connectorData
77+
var originalClaims map[string]interface{}
78+
79+
c.logger.Info("ExtendPayload called")
80+
81+
if err := json.Unmarshal(cdata, &cd); err != nil {
82+
return payload, err
83+
}
84+
if err := json.Unmarshal(payload, &originalClaims); err != nil {
85+
return payload, err
86+
}
87+
88+
// Experimental teams
89+
var teams []string
90+
teams = append(teams, cd.Introspect.Organizations.ManagingOrganization)
91+
originalClaims["teams"] = teams
92+
93+
extendedPayload, err := json.Marshal(originalClaims)
94+
if err != nil {
95+
return payload, err
96+
}
97+
return extendedPayload, nil
98+
}
99+
```
100+
101+
This results in a `teams` claim being available in the id_token.
102+
103+
### Risks and Mitigations
104+
105+
Since the claims are mutated / extended from the upstream IDP, any consuming application should
106+
be aware of active payload extending of the connector. Care should be taken by the extender not to
107+
break or remove standard claims. All ExtendPayload implementation should include tests to cover
108+
all common scenarios.
109+
110+
Any connector not implementing the `ExtendPayload` interface should function as before.
111+
112+
### Alternatives
113+
114+
- We looked at KeyCloak to support this but Dex is way lighter in deployment and maintenance.
115+
- Commercial IDP offerings have similar filtering/mutating capabilities but have a lock-in disadvantage.
116+
117+
## Future Improvements
118+
119+
- An DEP will be submitted to support `Dynamic scopes support`
120+
- We want to explore implementing a generic pluggable filtering mechanism which is connector agnostic

0 commit comments

Comments
 (0)