fix(hardening): give application a safe default Grant scope
This commit is contained in:
@@ -21,6 +21,13 @@ from .provenance_grants import GrantAuthorization, GrantVerifier, SQLiteGrantSto
|
|||||||
from .provenance_scoped import ScopedLeastPrivilegeProvenanceWriter
|
from .provenance_scoped import ScopedLeastPrivilegeProvenanceWriter
|
||||||
|
|
||||||
|
|
||||||
|
APPLICATION_PROVENANCE_SCOPE = (
|
||||||
|
ExecutionPath.RUNTIME_EXECUTE.value,
|
||||||
|
ExecutionPath.EVIDENCE_WRITE.value,
|
||||||
|
ExecutionPath.AUDIT.value,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class AuthorizationWriter(Protocol):
|
class AuthorizationWriter(Protocol):
|
||||||
def authorize_deployment(self, **values: Any) -> Any: ...
|
def authorize_deployment(self, **values: Any) -> Any: ...
|
||||||
def authorize_rollback(self, **values: Any) -> Any: ...
|
def authorize_rollback(self, **values: Any) -> Any: ...
|
||||||
@@ -159,19 +166,10 @@ def grant_ids_from_environment(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
values = {
|
values = {path: os.getenv(_GRANT_ENV_BY_PATH[path], "").strip() for path in paths}
|
||||||
path: os.getenv(_GRANT_ENV_BY_PATH[path], "").strip()
|
missing = [_GRANT_ENV_BY_PATH[path] for path, value in values.items() if not value]
|
||||||
for path in paths
|
|
||||||
}
|
|
||||||
missing = [
|
|
||||||
_GRANT_ENV_BY_PATH[path]
|
|
||||||
for path, value in values.items()
|
|
||||||
if not value
|
|
||||||
]
|
|
||||||
if missing:
|
if missing:
|
||||||
raise RuntimeError(
|
raise RuntimeError(f"missing scoped Provenance Grant configuration: {missing}")
|
||||||
f"missing scoped Provenance Grant configuration: {missing}"
|
|
||||||
)
|
|
||||||
return values
|
return values
|
||||||
|
|
||||||
|
|
||||||
@@ -180,12 +178,13 @@ def build_provenance_writer_from_env(
|
|||||||
state_dir: str | Path | None = None,
|
state_dir: str | Path | None = None,
|
||||||
required: bool | None = None,
|
required: bool | None = None,
|
||||||
required_paths: Sequence[str] | None = None,
|
required_paths: Sequence[str] | None = None,
|
||||||
writer_id: str = "aios-v2-scoped-grant-writer",
|
writer_id: str = "aios-v2-application-grant-writer",
|
||||||
) -> AuthorizationWriter | None:
|
) -> AuthorizationWriter | None:
|
||||||
"""从环境构建服务级最小权限 Writer。
|
"""从环境构建服务级最小权限 Writer。
|
||||||
|
|
||||||
生产强制模式必须显式声明当前进程需要的路径;仅加载这些路径对应的 Grant。
|
生产应用默认只加载 Runtime、Evidence、Audit Grant。Git、部署和回滚进程
|
||||||
旧全权限 Writer 只允许在显式关闭强制模式的候选/测试环境中使用。
|
必须显式传入自己的 ``required_paths``,不能继承应用默认范围。旧全权限 Writer
|
||||||
|
只允许在显式关闭强制模式的候选/测试环境中使用。
|
||||||
"""
|
"""
|
||||||
|
|
||||||
require_value = (
|
require_value = (
|
||||||
@@ -217,23 +216,21 @@ def build_provenance_writer_from_env(
|
|||||||
sorted(
|
sorted(
|
||||||
{
|
{
|
||||||
ExecutionPath(path).value
|
ExecutionPath(path).value
|
||||||
for path in (required_paths or ())
|
for path in (
|
||||||
|
required_paths
|
||||||
|
if required_paths is not None
|
||||||
|
else APPLICATION_PROVENANCE_SCOPE
|
||||||
|
)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
if require_value:
|
if require_value:
|
||||||
if not normalized_paths:
|
if not normalized_paths:
|
||||||
raise RuntimeError(
|
raise RuntimeError("production Run Provenance requires a non-empty service scope")
|
||||||
"production Run Provenance requires explicit service scope"
|
|
||||||
)
|
|
||||||
grant_ids = grant_ids_from_environment(required_paths=normalized_paths)
|
grant_ids = grant_ids_from_environment(required_paths=normalized_paths)
|
||||||
grant_store = SQLiteGrantStore(store_file)
|
grant_store = SQLiteGrantStore(store_file)
|
||||||
trusted_grants = GrantVerifier(
|
trusted_grants = GrantVerifier(parent_store, grant_store, {key_id: verifier})
|
||||||
parent_store,
|
|
||||||
grant_store,
|
|
||||||
{key_id: verifier},
|
|
||||||
)
|
|
||||||
return ScopedLeastPrivilegeProvenanceWriter(
|
return ScopedLeastPrivilegeProvenanceWriter(
|
||||||
trusted_grants,
|
trusted_grants,
|
||||||
receipt_root,
|
receipt_root,
|
||||||
|
|||||||
Reference in New Issue
Block a user