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

Fields

No fields configured for Task.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions