feat: trust/exposure fields — installVerification, keyPinned, exposure
Some checks failed
Security / Security check (push) Failing after 2s
Some checks failed
Security / Security check (push) Failing after 2s
Regenerated stubs for the additive proto: per-entry StoreEntry.installVerification, StoreSource.keyPinned, the ListStoresResponse policy snapshot (requireSignatures / trustedPublisherCount) and DeclaredService.exposure. New listStoresFull() exposes the response-level snapshot; listStores() stays as the plain source list. Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
This commit is contained in:
parent
d9ef3ecdb6
commit
0eafaa763a
4 changed files with 143 additions and 4 deletions
|
|
@ -6,6 +6,14 @@ for the authoritative per-release detail.
|
|||
|
||||
## Unreleased
|
||||
|
||||
- Regenerated stubs for the trust/exposure proto additions:
|
||||
`StoreEntry.installVerification` (pinned-key / trusted-publishers /
|
||||
unverified / blocked / federated), `StoreSource.keyPinned`,
|
||||
`ListStoresResponse.requireSignatures` / `trustedPublisherCount`,
|
||||
`DeclaredService.exposure` (loopback/private/public/unknown).
|
||||
- New `listStoresFull()` returning the full response incl. the
|
||||
policy snapshot; `listStores()` unchanged.
|
||||
|
||||
- `InvocationList.detachedEnabled`: whether the operator enabled
|
||||
detached invocations — monitor UIs can distinguish "feature off"
|
||||
from "on, but no runs yet". Regenerated stubs.
|
||||
|
|
|
|||
|
|
@ -4962,12 +4962,14 @@ class DeclaredService extends $pb.GeneratedMessage {
|
|||
$core.String? endpoint,
|
||||
$core.String? healthPath,
|
||||
$core.Iterable<$core.String>? tags,
|
||||
$core.String? exposure,
|
||||
}) {
|
||||
final result = create();
|
||||
if (name != null) result.name = name;
|
||||
if (endpoint != null) result.endpoint = endpoint;
|
||||
if (healthPath != null) result.healthPath = healthPath;
|
||||
if (tags != null) result.tags.addAll(tags);
|
||||
if (exposure != null) result.exposure = exposure;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -4988,6 +4990,7 @@ class DeclaredService extends $pb.GeneratedMessage {
|
|||
..aOS(2, _omitFieldNames ? '' : 'endpoint')
|
||||
..aOS(3, _omitFieldNames ? '' : 'healthPath')
|
||||
..pPS(4, _omitFieldNames ? '' : 'tags')
|
||||
..aOS(5, _omitFieldNames ? '' : 'exposure')
|
||||
..hasRequiredFields = false;
|
||||
|
||||
@$core.Deprecated('See https://github.com/google/protobuf.dart/issues/998.')
|
||||
|
|
@ -5039,6 +5042,23 @@ class DeclaredService extends $pb.GeneratedMessage {
|
|||
|
||||
@$pb.TagNumber(4)
|
||||
$pb.PbList<$core.String> get tags => $_getList(3);
|
||||
|
||||
/// Network reach of `endpoint`, classified from its host part
|
||||
/// (no DNS lookups — named hosts other than localhost report
|
||||
/// "unknown"):
|
||||
/// "loopback" — 127.0.0.0/8, ::1, localhost
|
||||
/// "private" — RFC1918 / ULA / link-local ranges
|
||||
/// "public" — any other literal IP
|
||||
/// "unknown" — unparseable, or a hostname we cannot judge
|
||||
/// Empty from pre-0.23 hubs.
|
||||
@$pb.TagNumber(5)
|
||||
$core.String get exposure => $_getSZ(4);
|
||||
@$pb.TagNumber(5)
|
||||
set exposure($core.String value) => $_setString(4, value);
|
||||
@$pb.TagNumber(5)
|
||||
$core.bool hasExposure() => $_has(4);
|
||||
@$pb.TagNumber(5)
|
||||
void clearExposure() => $_clearField(5);
|
||||
}
|
||||
|
||||
class StoreEntry extends $pb.GeneratedMessage {
|
||||
|
|
@ -5067,6 +5087,7 @@ class StoreEntry extends $pb.GeneratedMessage {
|
|||
$core.String? source,
|
||||
$core.String? canonicalCategory,
|
||||
$core.String? canonicalCategoryLabel,
|
||||
$core.String? installVerification,
|
||||
}) {
|
||||
final result = create();
|
||||
if (name != null) result.name = name;
|
||||
|
|
@ -5096,6 +5117,8 @@ class StoreEntry extends $pb.GeneratedMessage {
|
|||
if (canonicalCategory != null) result.canonicalCategory = canonicalCategory;
|
||||
if (canonicalCategoryLabel != null)
|
||||
result.canonicalCategoryLabel = canonicalCategoryLabel;
|
||||
if (installVerification != null)
|
||||
result.installVerification = installVerification;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -5136,6 +5159,7 @@ class StoreEntry extends $pb.GeneratedMessage {
|
|||
..aOS(22, _omitFieldNames ? '' : 'source')
|
||||
..aOS(23, _omitFieldNames ? '' : 'canonicalCategory')
|
||||
..aOS(24, _omitFieldNames ? '' : 'canonicalCategoryLabel')
|
||||
..aOS(25, _omitFieldNames ? '' : 'installVerification')
|
||||
..hasRequiredFields = false;
|
||||
|
||||
@$core.Deprecated('See https://github.com/google/protobuf.dart/issues/998.')
|
||||
|
|
@ -5396,6 +5420,33 @@ class StoreEntry extends $pb.GeneratedMessage {
|
|||
$core.bool hasCanonicalCategoryLabel() => $_has(23);
|
||||
@$pb.TagNumber(24)
|
||||
void clearCanonicalCategoryLabel() => $_clearField(24);
|
||||
|
||||
/// How an install of this entry would be verified, given its
|
||||
/// origin store and the operator's CURRENT security policy. The
|
||||
/// hub computes this with the same resolution the install path
|
||||
/// enforces (pinned store key -> trusted publishers -> policy),
|
||||
/// so the display can never disagree with the gate:
|
||||
/// "pinned-key" — verified against the origin store's
|
||||
/// pinned cosign key (or the built-in
|
||||
/// official key for bundled/official)
|
||||
/// "trusted-publishers" — verified against the applicable
|
||||
/// trusted-publisher list
|
||||
/// "unverified" — require_signatures is off; installs
|
||||
/// are NOT signature-checked
|
||||
/// "blocked" — policy requires signatures but no key
|
||||
/// material applies to this source; an
|
||||
/// install would be refused
|
||||
/// "federated" — bridge entry (MCP/n8n/…); no bundle
|
||||
/// signature applies
|
||||
/// Empty from pre-0.23 hubs — clients keep their generic note.
|
||||
@$pb.TagNumber(25)
|
||||
$core.String get installVerification => $_getSZ(24);
|
||||
@$pb.TagNumber(25)
|
||||
set installVerification($core.String value) => $_setString(24, value);
|
||||
@$pb.TagNumber(25)
|
||||
$core.bool hasInstallVerification() => $_has(24);
|
||||
@$pb.TagNumber(25)
|
||||
void clearInstallVerification() => $_clearField(25);
|
||||
}
|
||||
|
||||
class ChannelStatusResponse extends $pb.GeneratedMessage {
|
||||
|
|
@ -8963,12 +9014,14 @@ class StoreSource extends $pb.GeneratedMessage {
|
|||
$core.String? url,
|
||||
$core.bool? removable,
|
||||
$core.int? moduleCount,
|
||||
$core.bool? keyPinned,
|
||||
}) {
|
||||
final result = create();
|
||||
if (name != null) result.name = name;
|
||||
if (url != null) result.url = url;
|
||||
if (removable != null) result.removable = removable;
|
||||
if (moduleCount != null) result.moduleCount = moduleCount;
|
||||
if (keyPinned != null) result.keyPinned = keyPinned;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -8989,6 +9042,7 @@ class StoreSource extends $pb.GeneratedMessage {
|
|||
..aOS(2, _omitFieldNames ? '' : 'url')
|
||||
..aOB(3, _omitFieldNames ? '' : 'removable')
|
||||
..aI(4, _omitFieldNames ? '' : 'moduleCount')
|
||||
..aOB(5, _omitFieldNames ? '' : 'keyPinned')
|
||||
..hasRequiredFields = false;
|
||||
|
||||
@$core.Deprecated('See https://github.com/google/protobuf.dart/issues/998.')
|
||||
|
|
@ -9049,14 +9103,32 @@ class StoreSource extends $pb.GeneratedMessage {
|
|||
$core.bool hasModuleCount() => $_has(3);
|
||||
@$pb.TagNumber(4)
|
||||
void clearModuleCount() => $_clearField(4);
|
||||
|
||||
/// True when this store pins a cosign publisher key
|
||||
/// (`trust.public_key_pem`, or the built-in official key for the
|
||||
/// bundled seed) — installs from it are verified against that key
|
||||
/// whenever signature checking is on.
|
||||
@$pb.TagNumber(5)
|
||||
$core.bool get keyPinned => $_getBF(4);
|
||||
@$pb.TagNumber(5)
|
||||
set keyPinned($core.bool value) => $_setBool(4, value);
|
||||
@$pb.TagNumber(5)
|
||||
$core.bool hasKeyPinned() => $_has(4);
|
||||
@$pb.TagNumber(5)
|
||||
void clearKeyPinned() => $_clearField(5);
|
||||
}
|
||||
|
||||
class ListStoresResponse extends $pb.GeneratedMessage {
|
||||
factory ListStoresResponse({
|
||||
$core.Iterable<StoreSource>? stores,
|
||||
$core.bool? requireSignatures,
|
||||
$core.int? trustedPublisherCount,
|
||||
}) {
|
||||
final result = create();
|
||||
if (stores != null) result.stores.addAll(stores);
|
||||
if (requireSignatures != null) result.requireSignatures = requireSignatures;
|
||||
if (trustedPublisherCount != null)
|
||||
result.trustedPublisherCount = trustedPublisherCount;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -9075,6 +9147,8 @@ class ListStoresResponse extends $pb.GeneratedMessage {
|
|||
createEmptyInstance: create)
|
||||
..pPM<StoreSource>(1, _omitFieldNames ? '' : 'stores',
|
||||
subBuilder: StoreSource.create)
|
||||
..aOB(2, _omitFieldNames ? '' : 'requireSignatures')
|
||||
..aI(3, _omitFieldNames ? '' : 'trustedPublisherCount')
|
||||
..hasRequiredFields = false;
|
||||
|
||||
@$core.Deprecated('See https://github.com/google/protobuf.dart/issues/998.')
|
||||
|
|
@ -9098,6 +9172,28 @@ class ListStoresResponse extends $pb.GeneratedMessage {
|
|||
|
||||
@$pb.TagNumber(1)
|
||||
$pb.PbList<StoreSource> get stores => $_getList(0);
|
||||
|
||||
/// Operator policy snapshot so store UIs can say honestly whether
|
||||
/// installs are signature-checked at all.
|
||||
@$pb.TagNumber(2)
|
||||
$core.bool get requireSignatures => $_getBF(1);
|
||||
@$pb.TagNumber(2)
|
||||
set requireSignatures($core.bool value) => $_setBool(1, value);
|
||||
@$pb.TagNumber(2)
|
||||
$core.bool hasRequireSignatures() => $_has(1);
|
||||
@$pb.TagNumber(2)
|
||||
void clearRequireSignatures() => $_clearField(2);
|
||||
|
||||
/// Number of globally trusted publisher identities
|
||||
/// (`security.trusted_publishers`).
|
||||
@$pb.TagNumber(3)
|
||||
$core.int get trustedPublisherCount => $_getIZ(2);
|
||||
@$pb.TagNumber(3)
|
||||
set trustedPublisherCount($core.int value) => $_setSignedInt32(2, value);
|
||||
@$pb.TagNumber(3)
|
||||
$core.bool hasTrustedPublisherCount() => $_has(2);
|
||||
@$pb.TagNumber(3)
|
||||
void clearTrustedPublisherCount() => $_clearField(3);
|
||||
}
|
||||
|
||||
class AddStoreRequest extends $pb.GeneratedMessage {
|
||||
|
|
|
|||
|
|
@ -1311,6 +1311,7 @@ const DeclaredService$json = {
|
|||
{'1': 'endpoint', '3': 2, '4': 1, '5': 9, '10': 'endpoint'},
|
||||
{'1': 'health_path', '3': 3, '4': 1, '5': 9, '10': 'healthPath'},
|
||||
{'1': 'tags', '3': 4, '4': 3, '5': 9, '10': 'tags'},
|
||||
{'1': 'exposure', '3': 5, '4': 1, '5': 9, '10': 'exposure'},
|
||||
],
|
||||
};
|
||||
|
||||
|
|
@ -1318,7 +1319,7 @@ const DeclaredService$json = {
|
|||
final $typed_data.Uint8List declaredServiceDescriptor = $convert.base64Decode(
|
||||
'Cg9EZWNsYXJlZFNlcnZpY2USEgoEbmFtZRgBIAEoCVIEbmFtZRIaCghlbmRwb2ludBgCIAEoCV'
|
||||
'IIZW5kcG9pbnQSHwoLaGVhbHRoX3BhdGgYAyABKAlSCmhlYWx0aFBhdGgSEgoEdGFncxgEIAMo'
|
||||
'CVIEdGFncw==');
|
||||
'CVIEdGFncxIaCghleHBvc3VyZRgFIAEoCVIIZXhwb3N1cmU=');
|
||||
|
||||
@$core.Deprecated('Use storeEntryDescriptor instead')
|
||||
const StoreEntry$json = {
|
||||
|
|
@ -1372,6 +1373,13 @@ const StoreEntry$json = {
|
|||
'5': 9,
|
||||
'10': 'canonicalCategoryLabel'
|
||||
},
|
||||
{
|
||||
'1': 'install_verification',
|
||||
'3': 25,
|
||||
'4': 1,
|
||||
'5': 9,
|
||||
'10': 'installVerification'
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
|
|
@ -1391,7 +1399,8 @@ final $typed_data.Uint8List storeEntryDescriptor = $convert.base64Decode(
|
|||
'oIcHJvdmlkZXIYFCABKAlSCHByb3ZpZGVyEh8KC3NvdXJjZV9raW5kGBUgASgJUgpzb3VyY2VL'
|
||||
'aW5kEhYKBnNvdXJjZRgWIAEoCVIGc291cmNlEi0KEmNhbm9uaWNhbF9jYXRlZ29yeRgXIAEoCV'
|
||||
'IRY2Fub25pY2FsQ2F0ZWdvcnkSOAoYY2Fub25pY2FsX2NhdGVnb3J5X2xhYmVsGBggASgJUhZj'
|
||||
'YW5vbmljYWxDYXRlZ29yeUxhYmVs');
|
||||
'YW5vbmljYWxDYXRlZ29yeUxhYmVsEjEKFGluc3RhbGxfdmVyaWZpY2F0aW9uGBkgASgJUhNpbn'
|
||||
'N0YWxsVmVyaWZpY2F0aW9u');
|
||||
|
||||
@$core.Deprecated('Use channelStatusResponseDescriptor instead')
|
||||
const ChannelStatusResponse$json = {
|
||||
|
|
@ -2179,6 +2188,7 @@ const StoreSource$json = {
|
|||
{'1': 'url', '3': 2, '4': 1, '5': 9, '10': 'url'},
|
||||
{'1': 'removable', '3': 3, '4': 1, '5': 8, '10': 'removable'},
|
||||
{'1': 'module_count', '3': 4, '4': 1, '5': 5, '10': 'moduleCount'},
|
||||
{'1': 'key_pinned', '3': 5, '4': 1, '5': 8, '10': 'keyPinned'},
|
||||
],
|
||||
};
|
||||
|
||||
|
|
@ -2186,7 +2196,7 @@ const StoreSource$json = {
|
|||
final $typed_data.Uint8List storeSourceDescriptor = $convert.base64Decode(
|
||||
'CgtTdG9yZVNvdXJjZRISCgRuYW1lGAEgASgJUgRuYW1lEhAKA3VybBgCIAEoCVIDdXJsEhwKCX'
|
||||
'JlbW92YWJsZRgDIAEoCFIJcmVtb3ZhYmxlEiEKDG1vZHVsZV9jb3VudBgEIAEoBVILbW9kdWxl'
|
||||
'Q291bnQ=');
|
||||
'Q291bnQSHQoKa2V5X3Bpbm5lZBgFIAEoCFIJa2V5UGlubmVk');
|
||||
|
||||
@$core.Deprecated('Use listStoresResponseDescriptor instead')
|
||||
const ListStoresResponse$json = {
|
||||
|
|
@ -2200,13 +2210,29 @@ const ListStoresResponse$json = {
|
|||
'6': '.chain.v1.StoreSource',
|
||||
'10': 'stores'
|
||||
},
|
||||
{
|
||||
'1': 'require_signatures',
|
||||
'3': 2,
|
||||
'4': 1,
|
||||
'5': 8,
|
||||
'10': 'requireSignatures'
|
||||
},
|
||||
{
|
||||
'1': 'trusted_publisher_count',
|
||||
'3': 3,
|
||||
'4': 1,
|
||||
'5': 5,
|
||||
'10': 'trustedPublisherCount'
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
/// Descriptor for `ListStoresResponse`. Decode as a `google.protobuf.DescriptorProto`.
|
||||
final $typed_data.Uint8List listStoresResponseDescriptor = $convert.base64Decode(
|
||||
'ChJMaXN0U3RvcmVzUmVzcG9uc2USLQoGc3RvcmVzGAEgAygLMhUuY2hhaW4udjEuU3RvcmVTb3'
|
||||
'VyY2VSBnN0b3Jlcw==');
|
||||
'VyY2VSBnN0b3JlcxItChJyZXF1aXJlX3NpZ25hdHVyZXMYAiABKAhSEXJlcXVpcmVTaWduYXR1'
|
||||
'cmVzEjYKF3RydXN0ZWRfcHVibGlzaGVyX2NvdW50GAMgASgFUhV0cnVzdGVkUHVibGlzaGVyQ2'
|
||||
'91bnQ=');
|
||||
|
||||
@$core.Deprecated('Use addStoreRequestDescriptor instead')
|
||||
const AddStoreRequest$json = {
|
||||
|
|
|
|||
|
|
@ -75,6 +75,7 @@ typedef CheckUpdateResponse = pb.CheckUpdateResponse;
|
|||
typedef ChannelStatusResponse = pb.ChannelStatusResponse;
|
||||
typedef ChannelEntry = pb.ChannelEntry;
|
||||
typedef StoreSource = pb.StoreSource;
|
||||
typedef ListStoresResponse = pb.ListStoresResponse;
|
||||
typedef AddStoreResponse = pb.AddStoreResponse;
|
||||
typedef RemoveStoreResponse = pb.RemoveStoreResponse;
|
||||
typedef SystemAiStatusResponse = pb.SystemAiStatusResponse;
|
||||
|
|
@ -764,6 +765,14 @@ class HubClient {
|
|||
return r.stores;
|
||||
}
|
||||
|
||||
/// Full store listing including the operator policy snapshot
|
||||
/// (`requireSignatures`, `trustedPublisherCount`) the hub reports
|
||||
/// alongside the sources since 0.23 — store UIs use it to state
|
||||
/// honestly whether installs are signature-checked at all.
|
||||
/// [listStores] stays as the plain source list.
|
||||
Future<ListStoresResponse> listStoresFull() =>
|
||||
_admin.listStores(pb.ListStoresRequest());
|
||||
|
||||
/// Register a new module store. The hub fetches + validates its index,
|
||||
/// persists it to config, and merges it live so its modules are
|
||||
/// immediately searchable + installable.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue