{"record":{"id":"f4fe9bfd9fdb181e","repo":"argoproj/argo-workflows","slug":"failed-to-create-jwt-encrypter-w","errorCode":null,"errorMessage":"failed to create JWT encrypter: %w","messagePattern":"failed to create JWT encrypter: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/auth/sso/sso.go","lineNumber":237,"sourceCode":"\tconfig := &oauth2.Config{\n\t\tClientID:     string(clientID),\n\t\tClientSecret: string(clientSecret),\n\t\tRedirectURL:  c.RedirectURL,\n\t\tEndpoint:     provider.Endpoint(),\n\t\tScopes:       append(c.Scopes, oidc.ScopeOpenID),\n\t}\n\tidTokenVerifier := provider.Verifier(&oidc.Config{ClientID: config.ClientID})\n\t// The server both mints and verifies these tokens, so symmetric AEAD is\n\t// sufficient: encryption with A256GCM also authenticates, and go-jose v4\n\t// only permits encrypt-only JWTs with symmetric algorithms. Asymmetric\n\t// encryption needed a nested signature, which pushed the cookie over the\n\t// 4KB browser limit (https://github.com/argoproj/argo-workflows/issues/16744).\n\t// The AES key is derived from the RSA key already stored in the secret so\n\t// that existing installations don't need a secret migration.\n\tencryptionKey := sha256.Sum256(x509.MarshalPKCS1PrivateKey(privateKey))\n\tencrypter, err := jose.NewEncrypter(jose.A256GCM, jose.Recipient{Algorithm: jose.DIRECT, Key: encryptionKey[:]}, &jose.EncrypterOptions{Compression: jose.DEFLATE})\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to create JWT encrypter: %w\", err)\n\t}\n\n\tvar filterGroupsRegex []*regexp.Regexp\n\tif len(c.FilterGroupsRegex) > 0 {\n\t\tfor _, regex := range c.FilterGroupsRegex {\n\t\t\tcompiledRegex, err := regexp.Compile(regex)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"failed to compile sso.filterGroupRegex: %s %w\", regex, err)\n\t\t\t}\n\t\t\tfilterGroupsRegex = append(filterGroupsRegex, compiledRegex)\n\t\t}\n\t}\n\n\tlf := logging.Fields{\"redirectUrl\": config.RedirectURL, \"logoutRedirectUrl\": c.LogoutRedirectURL, \"issuer\": c.Issuer, \"issuerAlias\": \"DISABLED\", \"clientId\": c.ClientID, \"scopes\": config.Scopes, \"insecureSkipVerify\": c.InsecureSkipVerify, \"filterGroupsRegex\": c.FilterGroupsRegex, \"rootCA\": c.RootCA}\n\tif c.IssuerAlias != \"\" {\n\t\tlf[\"issuerAlias\"] = c.IssuerAlias\n\t}\n\tlogger := logging.RequireLoggerFromContext(ctx).WithFields(lf)","sourceCodeStart":219,"sourceCodeEnd":255,"githubUrl":"https://github.com/argoproj/argo-workflows/blob/35bff19146f5a6ada77468c431f2624bd577e373/server/auth/sso/sso.go#L219-L255","documentation":"newSso derives an AES-256 key from the stored RSA key and builds a go-jose encrypter (A256GCM, DIRECT key management, DEFLATE compression) used to encrypt SSO session cookies. jose.NewEncrypter only fails on invalid algorithm/key combinations, so this error means the constructed JWE parameters were rejected — practically unreachable with the hardcoded constants, indicating a broken build or tampered dependency.","triggerScenarios":"jose.NewEncrypter returning an error in New(); with jose.A256GCM + jose.DIRECT + a 32-byte key this should never happen unless the go-jose library version in the vendored dependency rejects this combination.","commonSituations":"Dependency upgrade/downgrade of github.com/go-jose/go-jose where DIRECT key management for A256GCM is disallowed or the key length check changed; custom builds with modified constants.","solutions":["Read the wrapped error — it states which JWE parameter was rejected","Verify the vendored go-jose version matches go.mod (go mod verify / make vendor)","Rebuild argo-server from a clean tree (make cli / official image)","Report upstream if a supported go-jose version rejects A256GCM+DIRECT with a 32-byte key"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"key := sha256.Sum256(x509.MarshalPKCS1PrivateKey(privKey))\nif len(key) != 32 {\n    return fmt.Errorf(\"derived encryption key must be 32 bytes for A256GCM/DIRECT\")\n}","typeGuard":null,"tryCatchPattern":"if _, err := sso.New(ctx, cfg, secretsIf, baseHRef, secure); err != nil {\n    if strings.Contains(err.Error(), \"failed to create JWT encrypter\") {\n        return fmt.Errorf(\"go-jose rejected JWE parameters; verify vendored go-jose version: %w\", err)\n    }\n    return err\n}","preventionTips":["Pin the go-jose dependency version and run go mod verify in CI","Do not modify the A256GCM/DIRECT constants in sso.go without testing cookie issuance","Rebuild from a clean vendor tree when this appears after upgrades"],"tags":["jose","jwt","crypto","sso"],"backgroundTag":"jwe-encrypter-invalid-key","analyzedSha":"35bff19146f5a6ada77468c431f2624bd577e373","analyzedAt":"2026-09-03T19:34:35.908Z","contentChangedAt":"2026-09-03T19:34:35.908Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}