fix(plugin): allow unsigned Cloud plugins on dedicated workers

This commit is contained in:
RockChinQ
2026-09-28 14:26:10 +00:00
parent c18db122e1
commit ce118b4f41
4 changed files with 46 additions and 40 deletions
+2 -2
View File
@@ -49,8 +49,8 @@ dedicated profile.
| Deployment | SDK verification | Explicit `administrator_force` | Result |
| --- | --- | --- | --- |
| Cloud | valid envelope declaring `shared-runtime-v1` + `stateless-v1` | any | admitted to the shared singleton profile |
| Cloud | absent | any | reject before storage with `CERTIFIED_PLUGIN_CLOUD_CERTIFICATE_REQUIRED` |
| Cloud | malformed, untrusted, invalid, or non-shared | any | reject before storage with `CERTIFIED_PLUGIN_CLOUD_CERTIFICATE_INVALID` |
| Cloud | no signature | any | install on dedicated worker, without shared eligibility |
| Cloud | malformed, untrusted, invalid, or non-shared declaration | any | reject before storage with `CERTIFIED_PLUGIN_CLOUD_CERTIFICATE_INVALID`; do not treat a broken signature as unsigned |
| OSS | absent legacy envelope | any | admitted to the dedicated profile |
| OSS | valid envelope declaring `shared-runtime-v1` + `stateless-v1` | any | selected shared singleton profile |
| OSS | declaration signed by a **key this instance resolves** | false | reject with `CERTIFIED_PLUGIN_OSS_FORCE_REQUIRED` |
+5 -16
View File
@@ -43,12 +43,11 @@ class AdmissionDisposition(str, Enum):
class AdmissionCode(str, Enum):
SHARED_ELIGIBLE = 'CERTIFIED_PLUGIN_SHARED_ELIGIBLE'
CLOUD_CERTIFICATE_REQUIRED = 'CERTIFIED_PLUGIN_CLOUD_CERTIFICATE_REQUIRED'
UNSIGNED_DEDICATED = 'CERTIFIED_PLUGIN_UNSIGNED_DEDICATED'
CLOUD_CERTIFICATE_INVALID = 'CERTIFIED_PLUGIN_CLOUD_CERTIFICATE_INVALID'
OSS_LEGACY_DEDICATED = 'CERTIFIED_PLUGIN_OSS_LEGACY_DEDICATED'
OSS_FORCE_REQUIRED = 'CERTIFIED_PLUGIN_OSS_FORCE_REQUIRED'
OSS_FORCED_DEDICATED = 'CERTIFIED_PLUGIN_OSS_FORCED_DEDICATED'
OSS_CERTIFIED_DEDICATED = 'CERTIFIED_PLUGIN_OSS_CERTIFIED_DEDICATED'
OSS_UNTRUSTED_DEDICATED = 'CERTIFIED_PLUGIN_OSS_UNTRUSTED_DEDICATED'
@@ -196,7 +195,7 @@ def decide_plugin_admission(
facts: PluginCertificationFacts,
administrator_force: bool = False,
) -> PluginAdmissionDecision:
"""Apply Cloud fail-closed and OSS administrator-force admission rules."""
"""Only verified cross-tenant certificates grant shared placement."""
mode = DeploymentMode(deployment)
certificate = facts.certificate
@@ -207,26 +206,16 @@ def decide_plugin_admission(
SHARED_RUNTIME_V1,
)
if mode is DeploymentMode.CLOUD:
code = (
AdmissionCode.CLOUD_CERTIFICATE_REQUIRED
if certificate.verification is CertificateVerification.ABSENT
else AdmissionCode.CLOUD_CERTIFICATE_INVALID
)
return PluginAdmissionDecision(AdmissionDisposition.REJECTED, code, DEDICATED_RUNTIME)
if certificate.verification is CertificateVerification.ABSENT:
return PluginAdmissionDecision(
AdmissionDisposition.DEDICATED_ALLOWED,
AdmissionCode.OSS_LEGACY_DEDICATED,
AdmissionCode.UNSIGNED_DEDICATED if mode is DeploymentMode.CLOUD else AdmissionCode.OSS_LEGACY_DEDICATED,
DEDICATED_RUNTIME,
)
if certificate.verification is CertificateVerification.VALID:
if mode is DeploymentMode.CLOUD:
return PluginAdmissionDecision(
AdmissionDisposition.DEDICATED_ALLOWED,
AdmissionCode.OSS_CERTIFIED_DEDICATED,
DEDICATED_RUNTIME,
AdmissionDisposition.REJECTED, AdmissionCode.CLOUD_CERTIFICATE_INVALID, DEDICATED_RUNTIME
)
# A self-hosted deployment that has not configured the issuer key ring cannot
@@ -29,6 +29,7 @@ pytestmark = pytest.mark.integration
('deployment', 'archive_kind', 'administrator_force', 'expected_profile'),
[
('cloud', 'signed_shared', False, 'shared-runtime-v1'),
('cloud', 'legacy', False, 'dedicated'),
('oss', 'signed_shared', False, 'shared-runtime-v1'),
('oss', 'legacy', False, 'dedicated'),
('oss', 'forged_shared', True, 'dedicated'),
@@ -75,7 +76,7 @@ async def test_install_plugin_admits_archive_before_persistence_and_applies_sele
@pytest.mark.asyncio
@pytest.mark.parametrize('archive_kind', ['legacy', 'invalid_shared'])
@pytest.mark.parametrize('archive_kind', ['invalid_shared'])
async def test_cloud_rejects_untrusted_archive_before_storage_persistence_or_runtime_apply(archive_kind: str) -> None:
package, trusted_public_keys = _archive(archive_kind)
connector, _execution_context, _binding = _connector('cloud', trusted_public_keys)
@@ -180,26 +181,20 @@ async def test_marketplace_version_selection_keeps_certificate_gate_and_single_a
if requested_version is not None:
info['plugin_version'] = requested_version
task_context = TaskContext.new()
if archive_kind == 'legacy':
with pytest.raises(ValueError, match='CERTIFIED_PLUGIN_CLOUD_CERTIFICATE_REQUIRED'):
await connector.install_plugin(PluginInstallSource.MARKETPLACE, info, task_context)
connector._store_artifact_package.assert_not_awaited()
connector._persist_installation_package.assert_not_awaited()
connector.handler.apply_plugin_installation.assert_not_awaited()
connector._refresh_runner_registry.assert_not_awaited()
else:
await connector.install_plugin(PluginInstallSource.MARKETPLACE, info, task_context)
persisted_info = connector._persist_installation_package.await_args.kwargs['install_info']
assert persisted_info['plugin_version'] == '1.0.0'
assert persisted_info['_certification']['runtime_profile'] == 'shared-runtime-v1'
connector.handler.apply_plugin_installation.assert_awaited_once_with(
binding,
artifact_package=package,
enabled=True,
execution_mode=PluginExecutionMode.SHARED_CERTIFIED,
)
connector._refresh_runner_registry.assert_awaited_once()
assert task_context.metadata['progress_percent'] == 100
await connector.install_plugin(PluginInstallSource.MARKETPLACE, info, task_context)
persisted_info = connector._persist_installation_package.await_args.kwargs['install_info']
assert persisted_info['plugin_version'] == '1.0.0'
assert persisted_info['_certification']['runtime_profile'] == (
'shared-runtime-v1' if archive_kind == 'signed_shared' else 'dedicated'
)
connector.handler.apply_plugin_installation.assert_awaited_once_with(
binding,
artifact_package=package,
enabled=True,
execution_mode=(PluginExecutionMode.SHARED_CERTIFIED if archive_kind == 'signed_shared' else PluginExecutionMode.DEDICATED),
)
connector._refresh_runner_registry.assert_awaited_once()
assert task_context.metadata['progress_percent'] == 100
if requested_version is not None:
# Confirmed migrations must fetch the reviewed release, never latest/MCP/skill.
assert len(requests) == 1
@@ -13,7 +13,8 @@ from langbot_plugin.entities.io.context import PluginExecutionMode
('deployment', 'certificate', 'certificate_id', 'force', 'expected_disposition', 'expected_code'),
[
('cloud', ('valid', 'shared-runtime-v1'), 'issuer', False, 'shared_eligible', 'CERTIFIED_PLUGIN_SHARED_ELIGIBLE'),
('cloud', ('absent', None), None, False, 'rejected', 'CERTIFIED_PLUGIN_CLOUD_CERTIFICATE_REQUIRED'),
('cloud', ('absent', None), None, False, 'dedicated_allowed', 'CERTIFIED_PLUGIN_UNSIGNED_DEDICATED'),
('cloud', ('absent', None), None, True, 'dedicated_allowed', 'CERTIFIED_PLUGIN_UNSIGNED_DEDICATED'),
('cloud', ('malformed', None), None, False, 'rejected', 'CERTIFIED_PLUGIN_CLOUD_CERTIFICATE_INVALID'),
(
'cloud',
@@ -134,6 +135,27 @@ def test_legacy_shared_certificate_without_stateless_contract_is_not_shared() ->
assert decision.disposition is AdmissionDisposition.REJECTED
def test_oss_does_not_treat_valid_nonshared_signature_as_dedicated_certification() -> None:
from langbot.pkg.plugin.certification import (
AdmissionDisposition, CertificateFacts, CertificateVerification,
PluginCertificationFacts, decide_plugin_admission,
)
decision = decide_plugin_admission(
deployment='oss',
facts=PluginCertificationFacts(
installation_uuid='00000000-0000-4000-8000-000000000001',
artifact_digest='a' * 64,
certificate=CertificateFacts(
verification=CertificateVerification.VALID,
runtime_profile=None,
certificate_id='issuer',
),
),
)
assert decision.disposition is AdmissionDisposition.ADMINISTRATOR_FORCE_REQUIRED
def test_archive_inspection_preserves_legacy_tuple_and_exposes_certificate_facts() -> None:
from langbot.pkg.plugin.archive import (
ArchiveCertificateState,