@backstage/plugin-auth-backend 0.20.4-next.0 → 0.21.0-next.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,72 @@
1
1
  # @backstage/plugin-auth-backend
2
2
 
3
+ ## 0.21.0-next.2
4
+
5
+ ### Minor Changes
6
+
7
+ - 7dd8463: **BREAKING**: The `saml` provider has been migrated from `passport-saml` to `@node-saml/passport-saml`.
8
+
9
+ This comes with breaking changes to config options:
10
+
11
+ - `audience` is now mandatory
12
+ - `wantAuthnResponseSigned` is now exposed and defaults to `true`
13
+ - `wantAssertionsSigned` is now exposed and defaults to `true`
14
+
15
+ ### Patch Changes
16
+
17
+ - 97f8724: Support additional algorithms in the `/.well-known/openid-configuration` endpoint.
18
+ - a9e0107: The auth backend will now refuse to issue user tokens are excessively large.
19
+ - d4cc552: The helper function `makeProfileInfo` and `PassportHelpers.transformProfile`
20
+ were refactored to use the `jose` library.
21
+ - 8e8a25d: Ability for user to configure backstage token expiration
22
+ - Updated dependencies
23
+ - @backstage/backend-common@0.21.0-next.2
24
+ - @backstage/backend-plugin-api@0.6.10-next.2
25
+ - @backstage/plugin-auth-backend-module-aws-alb-provider@0.1.0-next.1
26
+ - @backstage/plugin-auth-node@0.4.4-next.2
27
+ - @backstage/plugin-auth-backend-module-atlassian-provider@0.1.2-next.2
28
+ - @backstage/plugin-auth-backend-module-github-provider@0.1.7-next.2
29
+ - @backstage/plugin-auth-backend-module-gitlab-provider@0.1.7-next.2
30
+ - @backstage/plugin-auth-backend-module-google-provider@0.1.7-next.2
31
+ - @backstage/plugin-auth-backend-module-microsoft-provider@0.1.5-next.2
32
+ - @backstage/plugin-auth-backend-module-oauth2-provider@0.1.7-next.2
33
+ - @backstage/plugin-auth-backend-module-oidc-provider@0.1.0-next.2
34
+ - @backstage/plugin-auth-backend-module-okta-provider@0.0.3-next.2
35
+ - @backstage/plugin-auth-backend-module-gcp-iap-provider@0.2.4-next.2
36
+ - @backstage/plugin-auth-backend-module-oauth2-proxy-provider@0.1.2-next.2
37
+ - @backstage/plugin-catalog-node@1.6.2-next.2
38
+ - @backstage/config@1.1.1
39
+ - @backstage/catalog-client@1.6.0-next.1
40
+ - @backstage/catalog-model@1.4.4-next.0
41
+ - @backstage/errors@1.2.3
42
+ - @backstage/types@1.1.1
43
+
44
+ ## 0.20.4-next.1
45
+
46
+ ### Patch Changes
47
+
48
+ - 23a98f8: Migrated the AWS ALB auth provider to new `@backstage/plugin-auth-backend-module-aws-alb-provider` module package.
49
+ - Updated dependencies
50
+ - @backstage/catalog-model@1.4.4-next.0
51
+ - @backstage/catalog-client@1.6.0-next.1
52
+ - @backstage/backend-plugin-api@0.6.10-next.1
53
+ - @backstage/backend-common@0.21.0-next.1
54
+ - @backstage/plugin-auth-backend-module-aws-alb-provider@0.1.0-next.0
55
+ - @backstage/config@1.1.1
56
+ - @backstage/errors@1.2.3
57
+ - @backstage/plugin-auth-backend-module-atlassian-provider@0.1.2-next.1
58
+ - @backstage/plugin-auth-backend-module-gcp-iap-provider@0.2.4-next.1
59
+ - @backstage/plugin-auth-backend-module-github-provider@0.1.7-next.1
60
+ - @backstage/plugin-auth-backend-module-gitlab-provider@0.1.7-next.1
61
+ - @backstage/plugin-auth-backend-module-google-provider@0.1.7-next.1
62
+ - @backstage/plugin-auth-backend-module-microsoft-provider@0.1.5-next.1
63
+ - @backstage/plugin-auth-backend-module-oauth2-provider@0.1.7-next.1
64
+ - @backstage/plugin-auth-backend-module-oauth2-proxy-provider@0.1.2-next.1
65
+ - @backstage/plugin-auth-backend-module-oidc-provider@0.1.0-next.1
66
+ - @backstage/plugin-auth-backend-module-okta-provider@0.0.3-next.1
67
+ - @backstage/plugin-auth-node@0.4.4-next.1
68
+ - @backstage/plugin-catalog-node@1.6.2-next.1
69
+
3
70
  ## 0.20.4-next.0
4
71
 
5
72
  ### Patch Changes
package/README.md CHANGED
@@ -165,3 +165,14 @@ To try out SAML, you can use the mock identity provider:
165
165
  ## Links
166
166
 
167
167
  - [The Backstage homepage](https://backstage.io)
168
+
169
+ ## Configuring Token Expiration in App Config
170
+
171
+ If you need to change Backstage token expiration from the default value of one hour you can do so through configuration. Note that this is **not** the session duration, but rather the duration that the short-term cryptographic tokens are valid for. The expiration can not be set lower than 10 minutes or above 24 hours.
172
+
173
+ This is what the configuration looks like:
174
+
175
+ ```
176
+ auth:
177
+ backstageTokenExpiration: { minutes: <user_defined_value> }
178
+ ```
package/config.d.ts CHANGED
@@ -14,6 +14,8 @@
14
14
  * limitations under the License.
15
15
  */
16
16
 
17
+ import { HumanDuration } from '@backstage/types';
18
+
17
19
  export interface Config {
18
20
  /** Configuration options for the auth plugin */
19
21
  auth?: {
@@ -184,6 +186,10 @@ export interface Config {
184
186
  cfaccess?: {
185
187
  teamName: string;
186
188
  };
189
+ /**
190
+ * The backstage token expiration.
191
+ */
192
+ backstageTokenExpiration?: HumanDuration;
187
193
  };
188
194
  };
189
195
  }
package/dist/index.cjs.js CHANGED
@@ -13,11 +13,10 @@ var Auth0InternalStrategy = require('passport-auth0');
13
13
  var crypto = require('crypto');
14
14
  var url = require('url');
15
15
  var errors = require('@backstage/errors');
16
- var jwtDecoder = require('jwt-decode');
17
- var fetch = require('node-fetch');
18
- var NodeCache = require('node-cache');
19
16
  var jose = require('jose');
17
+ var pluginAuthBackendModuleAwsAlbProvider = require('@backstage/plugin-auth-backend-module-aws-alb-provider');
20
18
  var passportBitbucketOauth2 = require('passport-bitbucket-oauth2');
19
+ var fetch = require('node-fetch');
21
20
  var pluginAuthBackendModuleGcpIapProvider = require('@backstage/plugin-auth-backend-module-gcp-iap-provider');
22
21
  var pluginAuthBackendModuleGithubProvider = require('@backstage/plugin-auth-backend-module-github-provider');
23
22
  var pluginAuthBackendModuleGitlabProvider = require('@backstage/plugin-auth-backend-module-gitlab-provider');
@@ -28,7 +27,7 @@ var pluginAuthBackendModuleOauth2ProxyProvider = require('@backstage/plugin-auth
28
27
  var pluginAuthBackendModuleOidcProvider = require('@backstage/plugin-auth-backend-module-oidc-provider');
29
28
  var pluginAuthBackendModuleOktaProvider = require('@backstage/plugin-auth-backend-module-okta-provider');
30
29
  var passportOneloginOauth = require('passport-onelogin-oauth');
31
- var passportSaml = require('passport-saml');
30
+ var passportSaml = require('@node-saml/passport-saml');
32
31
  var passportOauth2 = require('passport-oauth2');
33
32
  var catalogClient = require('@backstage/catalog-client');
34
33
  var catalogModel = require('@backstage/catalog-model');
@@ -43,36 +42,16 @@ var passport = require('passport');
43
42
  var minimatch = require('minimatch');
44
43
  var backendCommon = require('@backstage/backend-common');
45
44
  var config = require('@backstage/config');
45
+ var types = require('@backstage/types');
46
46
 
47
47
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
48
48
 
49
- function _interopNamespace(e) {
50
- if (e && e.__esModule) return e;
51
- var n = Object.create(null);
52
- if (e) {
53
- Object.keys(e).forEach(function (k) {
54
- if (k !== 'default') {
55
- var d = Object.getOwnPropertyDescriptor(e, k);
56
- Object.defineProperty(n, k, d.get ? d : {
57
- enumerable: true,
58
- get: function () { return e[k]; }
59
- });
60
- }
61
- });
62
- }
63
- n["default"] = e;
64
- return Object.freeze(n);
65
- }
66
-
67
49
  var express__default = /*#__PURE__*/_interopDefaultLegacy(express);
68
50
  var Router__default = /*#__PURE__*/_interopDefaultLegacy(Router);
69
51
  var cookieParser__default = /*#__PURE__*/_interopDefaultLegacy(cookieParser);
70
52
  var Auth0InternalStrategy__default = /*#__PURE__*/_interopDefaultLegacy(Auth0InternalStrategy);
71
53
  var crypto__default = /*#__PURE__*/_interopDefaultLegacy(crypto);
72
- var crypto__namespace = /*#__PURE__*/_interopNamespace(crypto);
73
- var jwtDecoder__default = /*#__PURE__*/_interopDefaultLegacy(jwtDecoder);
74
54
  var fetch__default = /*#__PURE__*/_interopDefaultLegacy(fetch);
75
- var NodeCache__default = /*#__PURE__*/_interopDefaultLegacy(NodeCache);
76
55
  var session__default = /*#__PURE__*/_interopDefaultLegacy(session);
77
56
  var connectSessionKnex__default = /*#__PURE__*/_interopDefaultLegacy(connectSessionKnex);
78
57
  var passport__default = /*#__PURE__*/_interopDefaultLegacy(passport);
@@ -240,10 +219,10 @@ const ensuresXRequestedWith = (req) => {
240
219
 
241
220
  const prepareBackstageIdentityResponse = pluginAuthNode.prepareBackstageIdentityResponse;
242
221
 
243
- var __defProp$d = Object.defineProperty;
244
- var __defNormalProp$d = (obj, key, value) => key in obj ? __defProp$d(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
245
- var __publicField$d = (obj, key, value) => {
246
- __defNormalProp$d(obj, typeof key !== "symbol" ? key + "" : key, value);
222
+ var __defProp$c = Object.defineProperty;
223
+ var __defNormalProp$c = (obj, key, value) => key in obj ? __defProp$c(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
224
+ var __publicField$c = (obj, key, value) => {
225
+ __defNormalProp$c(obj, typeof key !== "symbol" ? key + "" : key, value);
247
226
  return value;
248
227
  };
249
228
  const THOUSAND_DAYS_MS = 1e3 * 24 * 60 * 60 * 1e3;
@@ -252,8 +231,8 @@ class OAuthAdapter {
252
231
  constructor(handlers, options) {
253
232
  this.handlers = handlers;
254
233
  this.options = options;
255
- __publicField$d(this, "baseCookieOptions");
256
- __publicField$d(this, "setNonceCookie", (res, nonce, cookieConfig) => {
234
+ __publicField$c(this, "baseCookieOptions");
235
+ __publicField$c(this, "setNonceCookie", (res, nonce, cookieConfig) => {
257
236
  res.cookie(`${this.options.providerId}-nonce`, nonce, {
258
237
  maxAge: TEN_MINUTES_MS,
259
238
  ...this.baseCookieOptions,
@@ -261,34 +240,34 @@ class OAuthAdapter {
261
240
  path: `${cookieConfig.path}/handler`
262
241
  });
263
242
  });
264
- __publicField$d(this, "setGrantedScopeCookie", (res, scope, cookieConfig) => {
243
+ __publicField$c(this, "setGrantedScopeCookie", (res, scope, cookieConfig) => {
265
244
  res.cookie(`${this.options.providerId}-granted-scope`, scope, {
266
245
  maxAge: THOUSAND_DAYS_MS,
267
246
  ...this.baseCookieOptions,
268
247
  ...cookieConfig
269
248
  });
270
249
  });
271
- __publicField$d(this, "getRefreshTokenFromCookie", (req) => {
250
+ __publicField$c(this, "getRefreshTokenFromCookie", (req) => {
272
251
  return req.cookies[`${this.options.providerId}-refresh-token`];
273
252
  });
274
- __publicField$d(this, "getGrantedScopeFromCookie", (req) => {
253
+ __publicField$c(this, "getGrantedScopeFromCookie", (req) => {
275
254
  return req.cookies[`${this.options.providerId}-granted-scope`];
276
255
  });
277
- __publicField$d(this, "setRefreshTokenCookie", (res, refreshToken, cookieConfig) => {
256
+ __publicField$c(this, "setRefreshTokenCookie", (res, refreshToken, cookieConfig) => {
278
257
  res.cookie(`${this.options.providerId}-refresh-token`, refreshToken, {
279
258
  maxAge: THOUSAND_DAYS_MS,
280
259
  ...this.baseCookieOptions,
281
260
  ...cookieConfig
282
261
  });
283
262
  });
284
- __publicField$d(this, "removeRefreshTokenCookie", (res, cookieConfig) => {
263
+ __publicField$c(this, "removeRefreshTokenCookie", (res, cookieConfig) => {
285
264
  res.cookie(`${this.options.providerId}-refresh-token`, "", {
286
265
  maxAge: 0,
287
266
  ...this.baseCookieOptions,
288
267
  ...cookieConfig
289
268
  });
290
269
  });
291
- __publicField$d(this, "getCookieConfig", (origin) => {
270
+ __publicField$c(this, "getCookieConfig", (origin) => {
292
271
  return this.options.cookieConfigurer({
293
272
  providerId: this.options.providerId,
294
273
  baseUrl: this.options.baseUrl,
@@ -470,7 +449,7 @@ const makeProfileInfo = (profile, idToken) => {
470
449
  let displayName = (_b = (_a = profile.displayName) != null ? _a : profile.username) != null ? _b : profile.id;
471
450
  if ((!email || !picture || !displayName) && idToken) {
472
451
  try {
473
- const decoded = jwtDecoder__default["default"](idToken);
452
+ const decoded = jose.decodeJwt(idToken);
474
453
  if (!email && decoded.email) {
475
454
  email = decoded.email;
476
455
  }
@@ -586,21 +565,21 @@ const executeFetchUserProfileStrategy = async (providerStrategy, accessToken) =>
586
565
  });
587
566
  };
588
567
 
589
- var __defProp$c = Object.defineProperty;
590
- var __defNormalProp$c = (obj, key, value) => key in obj ? __defProp$c(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
591
- var __publicField$c = (obj, key, value) => {
592
- __defNormalProp$c(obj, typeof key !== "symbol" ? key + "" : key, value);
568
+ var __defProp$b = Object.defineProperty;
569
+ var __defNormalProp$b = (obj, key, value) => key in obj ? __defProp$b(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
570
+ var __publicField$b = (obj, key, value) => {
571
+ __defNormalProp$b(obj, typeof key !== "symbol" ? key + "" : key, value);
593
572
  return value;
594
573
  };
595
574
  class Auth0AuthProvider {
596
575
  constructor(options) {
597
- __publicField$c(this, "_strategy");
598
- __publicField$c(this, "signInResolver");
599
- __publicField$c(this, "authHandler");
600
- __publicField$c(this, "resolverContext");
601
- __publicField$c(this, "audience");
602
- __publicField$c(this, "connection");
603
- __publicField$c(this, "connectionScope");
576
+ __publicField$b(this, "_strategy");
577
+ __publicField$b(this, "signInResolver");
578
+ __publicField$b(this, "authHandler");
579
+ __publicField$b(this, "resolverContext");
580
+ __publicField$b(this, "audience");
581
+ __publicField$b(this, "connection");
582
+ __publicField$b(this, "connectionScope");
604
583
  /**
605
584
  * Due to passport-auth0 forcing options.state = true,
606
585
  * passport-oauth2 requires express-session to be installed
@@ -609,7 +588,7 @@ class Auth0AuthProvider {
609
588
  * passport-oauth2, which is the StateStore implementation used when options.state = false,
610
589
  * allowing us to avoid using express-session in order to integrate with auth0.
611
590
  */
612
- __publicField$c(this, "store", {
591
+ __publicField$b(this, "store", {
613
592
  store(_req, cb) {
614
593
  cb(null, null);
615
594
  },
@@ -750,147 +729,14 @@ const auth0 = createAuthProviderIntegration({
750
729
  }
751
730
  });
752
731
 
753
- var __defProp$b = Object.defineProperty;
754
- var __defNormalProp$b = (obj, key, value) => key in obj ? __defProp$b(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
755
- var __publicField$b = (obj, key, value) => {
756
- __defNormalProp$b(obj, typeof key !== "symbol" ? key + "" : key, value);
757
- return value;
758
- };
759
- const ALB_JWT_HEADER = "x-amzn-oidc-data";
760
- const ALB_ACCESS_TOKEN_HEADER = "x-amzn-oidc-accesstoken";
761
- class AwsAlbAuthProvider {
762
- constructor(options) {
763
- __publicField$b(this, "region");
764
- __publicField$b(this, "issuer");
765
- __publicField$b(this, "resolverContext");
766
- __publicField$b(this, "keyCache");
767
- __publicField$b(this, "authHandler");
768
- __publicField$b(this, "signInResolver");
769
- __publicField$b(this, "getKey", async (header) => {
770
- if (!header.kid) {
771
- throw new errors.AuthenticationError("No key id was specified in header");
772
- }
773
- const optionalCacheKey = this.keyCache.get(header.kid);
774
- if (optionalCacheKey) {
775
- return crypto__namespace.createPublicKey(optionalCacheKey);
776
- }
777
- const keyText = await fetch__default["default"](
778
- `https://public-keys.auth.elb.${encodeURIComponent(
779
- this.region
780
- )}.amazonaws.com/${encodeURIComponent(header.kid)}`
781
- ).then((response) => response.text());
782
- const keyValue = crypto__namespace.createPublicKey(keyText);
783
- this.keyCache.set(
784
- header.kid,
785
- keyValue.export({ format: "pem", type: "spki" })
786
- );
787
- return keyValue;
788
- });
789
- this.region = options.region;
790
- this.issuer = options.issuer;
791
- this.authHandler = options.authHandler;
792
- this.signInResolver = options.signInResolver;
793
- this.resolverContext = options.resolverContext;
794
- this.keyCache = new NodeCache__default["default"]({ stdTTL: 3600 });
795
- }
796
- frameHandler() {
797
- return Promise.resolve(void 0);
798
- }
799
- async refresh(req, res) {
800
- try {
801
- const result = await this.getResult(req);
802
- const response = await this.handleResult(result);
803
- res.json(response);
804
- } catch (e) {
805
- throw new errors.AuthenticationError(
806
- "Exception occurred during AWS ALB token refresh",
807
- e
808
- );
809
- }
810
- }
811
- start() {
812
- return Promise.resolve(void 0);
813
- }
814
- async getResult(req) {
815
- const jwt = req.header(ALB_JWT_HEADER);
816
- const accessToken = req.header(ALB_ACCESS_TOKEN_HEADER);
817
- if (jwt === void 0) {
818
- throw new errors.AuthenticationError(
819
- `Missing ALB OIDC header: ${ALB_JWT_HEADER}`
820
- );
821
- }
822
- if (accessToken === void 0) {
823
- throw new errors.AuthenticationError(
824
- `Missing ALB OIDC header: ${ALB_ACCESS_TOKEN_HEADER}`
825
- );
826
- }
827
- try {
828
- const verifyResult = await jose.jwtVerify(jwt, this.getKey);
829
- const claims = verifyResult.payload;
830
- if (this.issuer && claims.iss !== this.issuer) {
831
- throw new errors.AuthenticationError("Issuer mismatch on JWT token");
832
- }
833
- const fullProfile = {
834
- provider: "unknown",
835
- id: claims.sub,
836
- displayName: claims.name,
837
- username: claims.email.split("@")[0].toLowerCase(),
838
- name: {
839
- familyName: claims.family_name,
840
- givenName: claims.given_name
841
- },
842
- emails: [{ value: claims.email.toLowerCase() }],
843
- photos: [{ value: claims.picture }]
844
- };
845
- return {
846
- fullProfile,
847
- expiresInSeconds: claims.exp,
848
- accessToken
849
- };
850
- } catch (e) {
851
- throw new Error(`Exception occurred during JWT processing: ${e}`);
852
- }
853
- }
854
- async handleResult(result) {
855
- const { profile } = await this.authHandler(result, this.resolverContext);
856
- const backstageIdentity = await this.signInResolver(
857
- {
858
- result,
859
- profile
860
- },
861
- this.resolverContext
862
- );
863
- return {
864
- providerInfo: {
865
- accessToken: result.accessToken,
866
- expiresInSeconds: result.expiresInSeconds
867
- },
868
- backstageIdentity: prepareBackstageIdentityResponse(backstageIdentity),
869
- profile
870
- };
871
- }
872
- }
873
732
  const awsAlb = createAuthProviderIntegration({
874
733
  create(options) {
875
- return ({ config, resolverContext }) => {
876
- const region = config.getString("region");
877
- const issuer = config.getOptionalString("iss");
878
- if ((options == null ? void 0 : options.signIn.resolver) === void 0) {
879
- throw new Error(
880
- "SignInResolver is required to use this authentication provider"
881
- );
882
- }
883
- const authHandler = (options == null ? void 0 : options.authHandler) ? options.authHandler : async ({ fullProfile }) => ({
884
- profile: makeProfileInfo(fullProfile)
885
- });
886
- return new AwsAlbAuthProvider({
887
- region,
888
- issuer,
889
- signInResolver: options == null ? void 0 : options.signIn.resolver,
890
- authHandler,
891
- resolverContext
892
- });
893
- };
734
+ var _a;
735
+ return pluginAuthNode.createProxyAuthProviderFactory({
736
+ authenticator: pluginAuthBackendModuleAwsAlbProvider.awsAlbAuthenticator,
737
+ profileTransform: options == null ? void 0 : options.authHandler,
738
+ signInResolver: (_a = options == null ? void 0 : options.signIn) == null ? void 0 : _a.resolver
739
+ });
894
740
  }
895
741
  });
896
742
 
@@ -1565,9 +1411,10 @@ class SamlAuthProvider {
1565
1411
  this.signInResolver = options.signInResolver;
1566
1412
  this.authHandler = options.authHandler;
1567
1413
  this.resolverContext = options.resolverContext;
1568
- this.strategy = new passportSaml.Strategy({ ...options }, (fullProfile, done) => {
1569
- done(void 0, { fullProfile });
1570
- });
1414
+ const verifier = (profile, done) => {
1415
+ done(null, { fullProfile: profile });
1416
+ };
1417
+ this.strategy = new passportSaml.Strategy(options, verifier, verifier);
1571
1418
  }
1572
1419
  async start(req, res) {
1573
1420
  const { url } = await executeRedirectStrategy(req, this.strategy, {});
@@ -1624,7 +1471,7 @@ const saml = createAuthProviderIntegration({
1624
1471
  callbackUrl: `${globalConfig.baseUrl}/${providerId}/handler/frame`,
1625
1472
  entryPoint: config.getString("entryPoint"),
1626
1473
  logoutUrl: config.getOptionalString("logoutUrl"),
1627
- audience: config.getOptionalString("audience"),
1474
+ audience: config.getString("audience"),
1628
1475
  issuer: config.getString("issuer"),
1629
1476
  cert: config.getString("cert"),
1630
1477
  privateKey: config.getOptionalString("privateKey"),
@@ -1634,6 +1481,10 @@ const saml = createAuthProviderIntegration({
1634
1481
  signatureAlgorithm: config.getOptionalString("signatureAlgorithm"),
1635
1482
  digestAlgorithm: config.getOptionalString("digestAlgorithm"),
1636
1483
  acceptedClockSkewMs: config.getOptionalNumber("acceptedClockSkewMs"),
1484
+ wantAuthnResponseSigned: config.getOptionalBoolean(
1485
+ "wantAuthnResponseSigned"
1486
+ ),
1487
+ wantAssertionsSigned: config.getOptionalBoolean("wantAssertionsSigned"),
1637
1488
  appUrl: globalConfig.appUrl,
1638
1489
  authHandler,
1639
1490
  signInResolver: (_a = options == null ? void 0 : options.signIn) == null ? void 0 : _a.resolver,
@@ -1991,7 +1842,18 @@ function createOidcRouter(options) {
1991
1842
  jwks_uri: `${baseUrl}/.well-known/jwks.json`,
1992
1843
  response_types_supported: ["id_token"],
1993
1844
  subject_types_supported: ["public"],
1994
- id_token_signing_alg_values_supported: ["RS256"],
1845
+ id_token_signing_alg_values_supported: [
1846
+ "RS256",
1847
+ "RS384",
1848
+ "RS512",
1849
+ "ES256",
1850
+ "ES384",
1851
+ "ES512",
1852
+ "PS256",
1853
+ "PS384",
1854
+ "PS512",
1855
+ "EdDSA"
1856
+ ],
1995
1857
  scopes_supported: ["openid"],
1996
1858
  token_endpoint_auth_methods_supported: [],
1997
1859
  claims_supported: ["sub"],
@@ -2020,6 +1882,7 @@ var __publicField$4 = (obj, key, value) => {
2020
1882
  return value;
2021
1883
  };
2022
1884
  const MS_IN_S$1 = 1e3;
1885
+ const MAX_TOKEN_LENGTH = 32768;
2023
1886
  class TokenFactory {
2024
1887
  constructor(options) {
2025
1888
  __publicField$4(this, "issuer");
@@ -2054,7 +1917,16 @@ class TokenFactory {
2054
1917
  if (!key.alg) {
2055
1918
  throw new errors.AuthenticationError("No algorithm was provided in the key");
2056
1919
  }
2057
- return new jose.SignJWT({ ...additionalClaims, iss, sub, ent, aud, iat, exp }).setProtectedHeader({ alg: key.alg, kid: key.kid }).setIssuer(iss).setAudience(aud).setSubject(sub).setIssuedAt(iat).setExpirationTime(exp).sign(await jose.importJWK(key));
1920
+ const claims = { ...additionalClaims, iss, sub, ent, aud, iat, exp };
1921
+ const token = await new jose.SignJWT(claims).setProtectedHeader({ alg: key.alg, kid: key.kid }).setIssuer(iss).setAudience(aud).setSubject(sub).setIssuedAt(iat).setExpirationTime(exp).sign(await jose.importJWK(key));
1922
+ if (token.length > MAX_TOKEN_LENGTH) {
1923
+ throw new Error(
1924
+ `Failed to issue a new user token. The resulting token is excessively large, with either too many ownership claims or too large custom claims. You likely have a bug either in the sign-in resolver or catalog data. The following claims were requested: '${JSON.stringify(
1925
+ claims
1926
+ )}'`
1927
+ );
1928
+ }
1929
+ return token;
2058
1930
  }
2059
1931
  // This will be called by other services that want to verify ID tokens.
2060
1932
  // It is important that it returns a list of all public keys that could
@@ -2631,7 +2503,25 @@ _database = new WeakMap();
2631
2503
  _promise = new WeakMap();
2632
2504
  let AuthDatabase = _AuthDatabase;
2633
2505
 
2634
- const BACKSTAGE_SESSION_EXPIRATION = 3600;
2506
+ const TOKEN_EXP_DEFAULT_S = 3600;
2507
+ const TOKEN_EXP_MIN_S = 600;
2508
+ const TOKEN_EXP_MAX_S = 86400;
2509
+ function readBackstageTokenExpiration(config$1) {
2510
+ const processingIntervalKey = "auth.backstageTokenExpiration";
2511
+ if (!config$1.has(processingIntervalKey)) {
2512
+ return TOKEN_EXP_DEFAULT_S;
2513
+ }
2514
+ const duration = config.readDurationFromConfig(config$1, {
2515
+ key: processingIntervalKey
2516
+ });
2517
+ const durationS = Math.round(types.durationToMilliseconds(duration) / 1e3);
2518
+ if (durationS < TOKEN_EXP_MIN_S) {
2519
+ return TOKEN_EXP_MIN_S;
2520
+ } else if (durationS > TOKEN_EXP_MAX_S) {
2521
+ return TOKEN_EXP_MAX_S;
2522
+ }
2523
+ return durationS;
2524
+ }
2635
2525
 
2636
2526
  var __defProp = Object.defineProperty;
2637
2527
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
@@ -2698,8 +2588,8 @@ async function createRouter(options) {
2698
2588
  const router = Router__default["default"]();
2699
2589
  const appUrl = config.getString("app.baseUrl");
2700
2590
  const authUrl = await discovery.getExternalBaseUrl("auth");
2591
+ const backstageTokenExpiration = readBackstageTokenExpiration(config);
2701
2592
  const authDb = AuthDatabase.create(database);
2702
- const sessionExpirationSeconds = BACKSTAGE_SESSION_EXPIRATION;
2703
2593
  const keyStore = await KeyStores.fromConfig(config, {
2704
2594
  logger,
2705
2595
  database: authDb
@@ -2710,7 +2600,7 @@ async function createRouter(options) {
2710
2600
  {
2711
2601
  logger: logger.child({ component: "token-factory" }),
2712
2602
  issuer: authUrl,
2713
- sessionExpirationSeconds
2603
+ sessionExpirationSeconds: backstageTokenExpiration
2714
2604
  },
2715
2605
  keyStore
2716
2606
  );
@@ -2718,7 +2608,7 @@ async function createRouter(options) {
2718
2608
  tokenIssuer = new TokenFactory({
2719
2609
  issuer: authUrl,
2720
2610
  keyStore,
2721
- keyDurationSeconds: sessionExpirationSeconds,
2611
+ keyDurationSeconds: backstageTokenExpiration,
2722
2612
  logger: logger.child({ component: "token-factory" }),
2723
2613
  algorithm: tokenFactoryAlgorithm != null ? tokenFactoryAlgorithm : config.getOptionalString("auth.identityTokenAlgorithm")
2724
2614
  });