feat(client): authToken parameter for Bearer auth
Some checks failed
Security / Security check (push) Failing after 1s

`HubClient` accepts an optional `authToken: String?` that
attaches `authorization: Bearer <token>` to every gRPC + gRPC-
Web call as default CallOptions metadata.

Operators with `auth.tokens:` configured on the hub now have
a one-line client-side wire-up:

  final client = HubClient(
    endpoint: HubEndpoint(host: '...', port: 50051),
    authToken: 'secret-from-1password-or-vault',
  );

Without `authToken`, calls go unauthenticated — the hub
either accepts (anonymous mode) or rejects with
`UNAUTHENTICATED` (16) when auth is required.

dart analyze + dart test green (4 tests).

Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
This commit is contained in:
flemming-it 2026-05-28 16:37:08 +02:00
parent ed92f337b4
commit 549f9df5c6

View file

@ -6,6 +6,7 @@
import 'dart:typed_data';
import 'package:grpc/grpc.dart' as grpc;
import 'package:grpc/grpc_connection_interface.dart';
import 'channel_factory_io.dart'
@ -92,12 +93,32 @@ class HubClient {
final grpc_hub.HubClient _hub;
final grpc_hub.HubAdminClient _admin;
HubClient._(this.endpoint, this._channel)
: _hub = grpc_hub.HubClient(_channel),
_admin = grpc_hub.HubAdminClient(_channel);
HubClient._(this.endpoint, this._channel, grpc.CallOptions? defaultOptions)
: _hub = grpc_hub.HubClient(_channel, options: defaultOptions),
_admin = grpc_hub.HubAdminClient(_channel, options: defaultOptions);
factory HubClient({HubEndpoint endpoint = const HubEndpoint()}) {
return HubClient._(endpoint, channel_factory.createChannel(endpoint));
/// Construct a client.
///
/// Supply [authToken] when the hub is configured with
/// `auth.tokens:` in operator config the value is sent as
/// `authorization: Bearer <authToken>` metadata on every
/// gRPC call. Without a token, calls are unauthenticated
/// (the hub may reject them with `UNAUTHENTICATED` (16) when
/// auth is required).
factory HubClient({
HubEndpoint endpoint = const HubEndpoint(),
String? authToken,
}) {
final defaultOptions = (authToken == null || authToken.isEmpty)
? null
: grpc.CallOptions(
metadata: {'authorization': 'Bearer $authToken'},
);
return HubClient._(
endpoint,
channel_factory.createChannel(endpoint),
defaultOptions,
);
}
/// Liveness probe. Returns true when the hub responds with