diff --git a/lib/src/generated/fai/v1/hub.pb.dart b/lib/src/generated/fai/v1/hub.pb.dart index 2343924..05af8d0 100644 --- a/lib/src/generated/fai/v1/hub.pb.dart +++ b/lib/src/generated/fai/v1/hub.pb.dart @@ -1056,6 +1056,7 @@ class LoggedEvent extends $pb.GeneratedMessage { $fixnum.Int64? durationMs, $core.String? error, $core.String? detail, + $core.String? callerName, }) { final result = create(); if (eventId != null) result.eventId = eventId; @@ -1070,6 +1071,7 @@ class LoggedEvent extends $pb.GeneratedMessage { if (durationMs != null) result.durationMs = durationMs; if (error != null) result.error = error; if (detail != null) result.detail = detail; + if (callerName != null) result.callerName = callerName; return result; } @@ -1098,6 +1100,7 @@ class LoggedEvent extends $pb.GeneratedMessage { ..aInt64(10, _omitFieldNames ? '' : 'durationMs') ..aOS(11, _omitFieldNames ? '' : 'error') ..aOS(12, _omitFieldNames ? '' : 'detail') + ..aOS(13, _omitFieldNames ? '' : 'callerName') ..hasRequiredFields = false; @$core.Deprecated('See https://github.com/google/protobuf.dart/issues/998.') @@ -1230,6 +1233,21 @@ class LoggedEvent extends $pb.GeneratedMessage { $core.bool hasDetail() => $_has(11); @$pb.TagNumber(12) void clearDetail() => $_clearField(12); + + /// Operator-friendly name of the token whose holder + /// triggered this event. Empty when the call was anonymous + /// (auth.tokens: not configured), when the event was emitted + /// by hub-internal code (boot housekeeping, federation + /// discovery), or when the row pre-dates the audit- + /// attribution migration (0006). + @$pb.TagNumber(13) + $core.String get callerName => $_getSZ(12); + @$pb.TagNumber(13) + set callerName($core.String value) => $_setString(12, value); + @$pb.TagNumber(13) + $core.bool hasCallerName() => $_has(12); + @$pb.TagNumber(13) + void clearCallerName() => $_clearField(13); } class SaveFlowRequest extends $pb.GeneratedMessage { @@ -5967,6 +5985,63 @@ class DefaultScopeResponse extends $pb.GeneratedMessage { $pb.PbList<$core.String> get knownProviders => $_getList(1); } +class ReloadAuthResponse extends $pb.GeneratedMessage { + factory ReloadAuthResponse({ + $core.int? tokenCount, + }) { + final result = create(); + if (tokenCount != null) result.tokenCount = tokenCount; + return result; + } + + ReloadAuthResponse._(); + + factory ReloadAuthResponse.fromBuffer($core.List<$core.int> data, + [$pb.ExtensionRegistry registry = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromBuffer(data, registry); + factory ReloadAuthResponse.fromJson($core.String json, + [$pb.ExtensionRegistry registry = $pb.ExtensionRegistry.EMPTY]) => + create()..mergeFromJson(json, registry); + + static final $pb.BuilderInfo _i = $pb.BuilderInfo( + _omitMessageNames ? '' : 'ReloadAuthResponse', + package: const $pb.PackageName(_omitMessageNames ? '' : 'fai.v1'), + createEmptyInstance: create) + ..aI(1, _omitFieldNames ? '' : 'tokenCount', fieldType: $pb.PbFieldType.OU3) + ..hasRequiredFields = false; + + @$core.Deprecated('See https://github.com/google/protobuf.dart/issues/998.') + ReloadAuthResponse clone() => deepCopy(); + @$core.Deprecated('See https://github.com/google/protobuf.dart/issues/998.') + ReloadAuthResponse copyWith(void Function(ReloadAuthResponse) updates) => + super.copyWith((message) => updates(message as ReloadAuthResponse)) + as ReloadAuthResponse; + + @$core.override + $pb.BuilderInfo get info_ => _i; + + @$core.pragma('dart2js:noInline') + static ReloadAuthResponse create() => ReloadAuthResponse._(); + @$core.override + ReloadAuthResponse createEmptyInstance() => create(); + @$core.pragma('dart2js:noInline') + static ReloadAuthResponse getDefault() => _defaultInstance ??= + $pb.GeneratedMessage.$_defaultFor(create); + static ReloadAuthResponse? _defaultInstance; + + /// Number of tokens loaded into the live store after the + /// swap. Operators sanity-check this against the number + /// they expected to have in `auth.tokens:`. + @$pb.TagNumber(1) + $core.int get tokenCount => $_getIZ(0); + @$pb.TagNumber(1) + set tokenCount($core.int value) => $_setUnsignedInt32(0, value); + @$pb.TagNumber(1) + $core.bool hasTokenCount() => $_has(0); + @$pb.TagNumber(1) + void clearTokenCount() => $_clearField(1); +} + class McpClientConfigEntry extends $pb.GeneratedMessage { factory McpClientConfigEntry({ $core.String? name, diff --git a/lib/src/generated/fai/v1/hub.pbgrpc.dart b/lib/src/generated/fai/v1/hub.pbgrpc.dart index 149f5c4..47dd11d 100644 --- a/lib/src/generated/fai/v1/hub.pbgrpc.dart +++ b/lib/src/generated/fai/v1/hub.pbgrpc.dart @@ -378,6 +378,20 @@ class HubAdminClient extends $grpc.Client { return $createUnaryCall(_$setDefaultScope, request, options: options); } + /// Re-read `auth.tokens:` from operator config + env vars and + /// atomically swap the live token store. Used by operators to + /// rotate tokens without restarting the daemon. Returns the + /// new token count. Errors if the new config is invalid (env + /// var missing, duplicate secret, no scopes, …) — the + /// existing store stays in place so a botched rotation can't + /// lock the operator out. + $grpc.ResponseFuture<$0.ReloadAuthResponse> reloadAuth( + $1.Empty request, { + $grpc.CallOptions? options, + }) { + return $createUnaryCall(_$reloadAuth, request, options: options); + } + /// List host services declared in the operator config. Each /// entry carries name + endpoint; reachability is operator-side /// (on-demand `fai service status` or Studio probe). @@ -721,6 +735,11 @@ class HubAdminClient extends $grpc.Client { '/fai.v1.HubAdmin/SetDefaultScope', ($0.SetDefaultScopeRequest value) => value.writeToBuffer(), $0.DefaultScopeResponse.fromBuffer); + static final _$reloadAuth = + $grpc.ClientMethod<$1.Empty, $0.ReloadAuthResponse>( + '/fai.v1.HubAdmin/ReloadAuth', + ($1.Empty value) => value.writeToBuffer(), + $0.ReloadAuthResponse.fromBuffer); static final _$listServices = $grpc.ClientMethod<$1.Empty, $0.ServiceList>( '/fai.v1.HubAdmin/ListServices', ($1.Empty value) => value.writeToBuffer(), @@ -1024,6 +1043,13 @@ abstract class HubAdminServiceBase extends $grpc.Service { ($core.List<$core.int> value) => $0.SetDefaultScopeRequest.fromBuffer(value), ($0.DefaultScopeResponse value) => value.writeToBuffer())); + $addMethod($grpc.ServiceMethod<$1.Empty, $0.ReloadAuthResponse>( + 'ReloadAuth', + reloadAuth_Pre, + false, + false, + ($core.List<$core.int> value) => $1.Empty.fromBuffer(value), + ($0.ReloadAuthResponse value) => value.writeToBuffer())); $addMethod($grpc.ServiceMethod<$1.Empty, $0.ServiceList>( 'ListServices', listServices_Pre, @@ -1392,6 +1418,14 @@ abstract class HubAdminServiceBase extends $grpc.Service { $async.Future<$0.DefaultScopeResponse> setDefaultScope( $grpc.ServiceCall call, $0.SetDefaultScopeRequest request); + $async.Future<$0.ReloadAuthResponse> reloadAuth_Pre( + $grpc.ServiceCall $call, $async.Future<$1.Empty> $request) async { + return reloadAuth($call, await $request); + } + + $async.Future<$0.ReloadAuthResponse> reloadAuth( + $grpc.ServiceCall call, $1.Empty request); + $async.Future<$0.ServiceList> listServices_Pre( $grpc.ServiceCall $call, $async.Future<$1.Empty> $request) async { return listServices($call, await $request); diff --git a/lib/src/generated/fai/v1/hub.pbjson.dart b/lib/src/generated/fai/v1/hub.pbjson.dart index e3888d4..f04ab35 100644 --- a/lib/src/generated/fai/v1/hub.pbjson.dart +++ b/lib/src/generated/fai/v1/hub.pbjson.dart @@ -356,6 +356,7 @@ const LoggedEvent$json = { {'1': 'duration_ms', '3': 10, '4': 1, '5': 3, '10': 'durationMs'}, {'1': 'error', '3': 11, '4': 1, '5': 9, '10': 'error'}, {'1': 'detail', '3': 12, '4': 1, '5': 9, '10': 'detail'}, + {'1': 'caller_name', '3': 13, '4': 1, '5': 9, '10': 'callerName'}, ], }; @@ -367,7 +368,8 @@ final $typed_data.Uint8List loggedEventDescriptor = $convert.base64Decode( '52b2NhdGlvbklkEhsKCWZsb3dfbmFtZRgGIAEoCVIIZmxvd05hbWUSFwoHc3RlcF9pZBgHIAEo' 'CVIGc3RlcElkEh8KC21vZHVsZV9uYW1lGAggASgJUgptb2R1bGVOYW1lEiUKDm1vZHVsZV92ZX' 'JzaW9uGAkgASgJUg1tb2R1bGVWZXJzaW9uEh8KC2R1cmF0aW9uX21zGAogASgDUgpkdXJhdGlv' - 'bk1zEhQKBWVycm9yGAsgASgJUgVlcnJvchIWCgZkZXRhaWwYDCABKAlSBmRldGFpbA=='); + 'bk1zEhQKBWVycm9yGAsgASgJUgVlcnJvchIWCgZkZXRhaWwYDCABKAlSBmRldGFpbBIfCgtjYW' + 'xsZXJfbmFtZRgNIAEoCVIKY2FsbGVyTmFtZQ=='); @$core.Deprecated('Use saveFlowRequestDescriptor instead') const SaveFlowRequest$json = { @@ -1391,6 +1393,18 @@ final $typed_data.Uint8List defaultScopeResponseDescriptor = $convert.base64Deco 'ChREZWZhdWx0U2NvcGVSZXNwb25zZRIUCgVzY29wZRgBIAMoCVIFc2NvcGUSJwoPa25vd25fcH' 'JvdmlkZXJzGAIgAygJUg5rbm93blByb3ZpZGVycw=='); +@$core.Deprecated('Use reloadAuthResponseDescriptor instead') +const ReloadAuthResponse$json = { + '1': 'ReloadAuthResponse', + '2': [ + {'1': 'token_count', '3': 1, '4': 1, '5': 13, '10': 'tokenCount'}, + ], +}; + +/// Descriptor for `ReloadAuthResponse`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List reloadAuthResponseDescriptor = $convert.base64Decode( + 'ChJSZWxvYWRBdXRoUmVzcG9uc2USHwoLdG9rZW5fY291bnQYASABKA1SCnRva2VuQ291bnQ='); + @$core.Deprecated('Use mcpClientConfigEntryDescriptor instead') const McpClientConfigEntry$json = { '1': 'McpClientConfigEntry', diff --git a/lib/src/hub_client.dart b/lib/src/hub_client.dart index b6446df..1ac69fc 100644 --- a/lib/src/hub_client.dart +++ b/lib/src/hub_client.dart @@ -188,6 +188,18 @@ class HubClient { ); } + /// Re-read `auth.tokens:` from operator config + env vars + /// and atomically swap the hub's live token store. Used by + /// operators to rotate tokens without restarting the daemon. + /// Returns the new token count after the swap. Throws when + /// the new config is invalid; the existing store stays in + /// place in that case so a botched rotation can't lock the + /// operator out. + Future reloadAuth() async { + final r = await _admin.reloadAuth(Empty()); + return r.tokenCount; + } + /// Server-streaming audit-log subscription. The hub first /// replays up to [backfill] historical events (oldest-last so /// the receiver sees them in chronological order), then keeps diff --git a/pubspec.yaml b/pubspec.yaml index 2d6ac9f..24be5e2 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: fai_client_sdk description: gRPC client SDK for the F∆I Platform hub. Used by F∆I Studio and Tier-3 domain apps. -version: 0.17.0 +version: 0.17.1 publish_to: 'none' repository: https://git.flemming.ai/fai/client-sdk-dart