Skip to content

Reduce verbosity of use.authentications(...) DSL for OAuth2/OIDC #1509

Description

@mcruzdev

Context

I have identified that defining named authentications via use.authentications(...) is excessively verbose—requiring five nested lambdas plus fully qualified enum constants just to configure a single OAuth2 client.

This is a developer experience (DX) issue rather than a correctness issue, but it makes workflow definitions significantly harder to read and maintain.

Current Verbose Pattern

Defining two named OAuth2 clients currently requires deeply nested builders:

.use(use -> {
    use.secrets("joogle", "jahoo")
        .authentications(auth -> {
            auth.authentication("joogle", a -> {
                a.oauth2(oauth2 -> {
                    oauth2.endpoints(e -> e.token("/auth/joogle/token"))
                        .client(client -> client
                            .id("${ $secret.joogle.clientId }")
                            .secret("${ $secret.joogle.clientSecret }")
                            .authentication(ClientAuthentication.CLIENT_SECRET_POST))
                        .authority(joogleBaseUrl)
                        .grant(OAuth2AuthenticationDataGrant.CLIENT_CREDENTIALS);
                });
            });

            auth.authentication("jahoo", a -> {
                a.oauth2(oauth2 -> {
                    oauth2.endpoints(e -> e.token("/auth/jahoo/oidc/token"))
                        .client(client -> client
                            .id("${ $secret.jahoo.clientId }")
                            .secret("${ $secret.jahoo.clientSecret }")
                            .authentication(ClientAuthentication.CLIENT_SECRET_POST))
                        .authority(jahooBaseUrl)
                        .grant(OAuth2AuthenticationDataGrant.CLIENT_CREDENTIALS);
                });
            });
        });
})

Existing Shorthands (Inline Only)

FuncDSL.oauth2(...) and FuncDSL.oidc(...) already provide compact helpers for inline (per-call) authentication.

// 4-argument shorthand — works well for inline authentication
FuncDSL.oauth2(
    baseUrl,
    CLIENT_CREDENTIALS,
    clientId,
    clientSecret
);

However, there is no equivalent shorthand for named authentications defined under use.authentications(...).

Named authentications are required when:

  • multiple tasks reuse the same credentials;
  • the oidc extension resolves authentication by policy name.

Proposal

Provide flatter helper methods in FuncDSL (or a new AuthDSL helper) that reduce the amount of nesting required for named authentication definitions.

Option A — Static Factory Methods for Named Authentications

.use(use -> use
    .secrets("joogle", "jahoo")
    .authentications(auth -> {
        auth.oauth2(
            "joogle",
            joogleBaseUrl,
            CLIENT_CREDENTIALS,
            "${ $secret.joogle.clientId }",
            "${ $secret.joogle.clientSecret }"
        );

        auth.oauth2(
            "jahoo",
            jahooBaseUrl,
            CLIENT_CREDENTIALS,
            "${ $secret.jahoo.clientId }",
            "${ $secret.jahoo.clientSecret }"
        );
    })
)

Option B — Builder with Overloads for Common Grant Types

.use(use -> use
    .secrets("joogle", "jahoo")
    .authentications(
        clientCredentials(
            "joogle",
            joogleBaseUrl,
            "${ $secret.joogle.clientId }",
            "${ $secret.joogle.clientSecret }"
        ),
        clientCredentials(
            "jahoo",
            jahooBaseUrl,
            "${ $secret.jahoo.clientId }",
            "${ $secret.jahoo.clientSecret }"
        )
    )
)

Option C — Upstream SDK Enhancement

Since the builder API lives in io.serverlessworkflow.fluent, this enhancement may be better implemented upstream in sdk-java by adding convenience overloads to the authentication builder.

Scope

  • Determine whether the shorthand belongs in Quarkus Flow's FuncDSL or should be proposed upstream to sdk-java.
  • Cover, at minimum, the following grant types:
    • client_credentials
    • password
    • token_exchange
  • Support optional endpoint customization (for example, a custom token endpoint path).
  • Keep the full lambda builder available for advanced use cases (scopes, audiences, subject tokens, actor tokens, etc.).

Acceptance Criteria

  • Named OAuth2/OIDC authentications can be defined with two or fewer levels of nesting (instead of the current five).
  • Common grant types (client_credentials, password) have dedicated shorthand methods.
  • The full lambda builder remains available for advanced configurations.
  • Existing examples and integration tests are updated to use the new shorthand where appropriate.
  • Documentation includes a before-and-after comparison.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions