@@ -20,6 +20,10 @@ import (
2020
2121// Options for the authcontrol middleware handlers Session and AccessControl.
2222type Options struct {
23+ // ServiceName is the name of the service using the middleware.
24+ // It is used to validate the `scope` claim for admin sessions.
25+ ServiceName string
26+
2327 // JWTsecret is required, and it is used for the JWT verification.
2428 // If a Project Store is also provided and the request has a project claim,
2529 // it could be replaced by the a specific verifier.
@@ -41,6 +45,11 @@ type Options struct {
4145}
4246
4347func (o * Options ) ApplyDefaults () {
48+ // Ensure a ServiceName is set, or else set to unknown to break scope.
49+ if o .ServiceName == "" {
50+ o .ServiceName = "!UNKNOWN!"
51+ }
52+
4453 // Set default access key functions if not provided.
4554 // We intentionally check for nil instead of len == 0 because
4655 // if you can pass an empty slice to have no access key defaults.
@@ -170,6 +179,7 @@ func Session(cfg Options) func(next http.Handler) http.Handler {
170179 adminClaim , _ := claims ["admin" ].(bool )
171180 projectClaim , _ := claims ["project" ].(float64 ) // Builder Admin API Secret Keys
172181 projectIDClaim , _ := claims ["project_id" ].(float64 ) // API->WaaS authentication
182+ scopeClaim , _ := claims ["scope" ].(string ) // use for additional context, ie. admin scope to specific service
173183
174184 if serviceClaim != "" {
175185 sessionType = proto .SessionType_S2S
@@ -201,7 +211,13 @@ func Session(cfg Options) func(next http.Handler) http.Handler {
201211 }
202212
203213 if adminClaim {
204- sessionType = proto .SessionType_Admin
214+ if scopeClaim == "" || scopeClaim == cfg .ServiceName || strings .Contains (scopeClaim , cfg .ServiceName ) {
215+ // Allow admin if no scope claim is provided or if it matches service name.
216+ sessionType = proto .SessionType_Admin
217+ } else {
218+ // Reduce to public if scope claim does not match.
219+ sessionType = proto .SessionType_Public
220+ }
205221 }
206222 }
207223
0 commit comments