security: reserve platform IAM groups in service group operations
Some checks failed
Some checks failed
Assistant: codex Assistant-Model: gpt-6-astra Assistant-Session: 01a1346b-72a4-7d40-b8bd-8b8ca346cfa2
This commit is contained in:
parent
84c5dbeec8
commit
e861f63513
3 changed files with 44 additions and 3 deletions
|
|
@ -425,7 +425,7 @@ def _discard(exc: BaseException) -> None:
|
||||||
|
|
||||||
|
|
||||||
SERVICE_GROUP = re.compile(r"[a-z][a-z0-9-]{1,62}")
|
SERVICE_GROUP = re.compile(r"[a-z][a-z0-9-]{1,62}")
|
||||||
RESERVED_GROUP_PREFIXES = ("tenant", "netkingdom-", "lldap_")
|
RESERVED_GROUP_PREFIXES = ("tenant", "netkingdom-", "net-kingdom-", "lldap_")
|
||||||
DIRECTORY_USERNAME = re.compile(r"[a-z][a-z0-9._-]{0,31}")
|
DIRECTORY_USERNAME = re.compile(r"[a-z][a-z0-9._-]{0,31}")
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -433,8 +433,9 @@ def _service_group_request(payload: dict[str, Any]) -> tuple[list[str], dict[str
|
||||||
"""Validate a service-access group request before anything is changed.
|
"""Validate a service-access group request before anything is changed.
|
||||||
|
|
||||||
Service-access groups gate sign-in to an internal service (SecurityCaseType
|
Service-access groups gate sign-in to an internal service (SecurityCaseType
|
||||||
oidc-browser-relying-party). Tenant, platform-suspension and LLDAP admin
|
oidc-browser-relying-party). Tenant, platform identity/administration,
|
||||||
groups are reserved and can never be touched through this path.
|
platform-suspension and LLDAP admin groups are reserved and can never be
|
||||||
|
touched through this path.
|
||||||
"""
|
"""
|
||||||
_required(payload, "groups", "idempotency_key", "correlation_id")
|
_required(payload, "groups", "idempotency_key", "correlation_id")
|
||||||
groups = payload["groups"]
|
groups = payload["groups"]
|
||||||
|
|
|
||||||
27
identity-provisioner/tests/test_platform_group_boundary.py
Normal file
27
identity-provisioner/tests/test_platform_group_boundary.py
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
"""Service group operations must never reach platform IAM groups."""
|
||||||
|
from unittest.mock import Mock
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
from provisioner import LLDAPProvisioner, dispatch
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("path", ["/v1/groups/ensure", "/v1/groups/revoke"])
|
||||||
|
@pytest.mark.parametrize("group", [
|
||||||
|
"net-kingdom-admins", "net-kingdom-users", "net-kingdom-future-role",
|
||||||
|
])
|
||||||
|
def test_platform_groups_refused_before_directory_login(path, group):
|
||||||
|
provider = LLDAPProvisioner(
|
||||||
|
base_url="https://directory.invalid", admin_password="synthetic-fixture",
|
||||||
|
)
|
||||||
|
provider._login = Mock(side_effect=AssertionError("must not contact directory"))
|
||||||
|
payload = {
|
||||||
|
"groups": ["activity-core-operators", group],
|
||||||
|
"members": {group: ["agent-codex"]},
|
||||||
|
"idempotency_key": "platform-boundary-test",
|
||||||
|
"correlation_id": "source-test",
|
||||||
|
"delete_if_empty": True,
|
||||||
|
}
|
||||||
|
with pytest.raises(ValueError, match="reserved"):
|
||||||
|
dispatch(provider, path, payload)
|
||||||
|
provider._login.assert_not_called()
|
||||||
|
|
@ -317,6 +317,19 @@ verification repair (only stale lifecycle guidance changed in two of them).
|
||||||
Incident cutover helpers, the full caller/root-output inventory and T03 remain
|
Incident cutover helpers, the full caller/root-output inventory and T03 remain
|
||||||
open. T02 stays progress; no workplan closure is claimed.
|
open. T02 stays progress; no workplan closure is claimed.
|
||||||
|
|
||||||
|
2026-10-14 group-provider boundary follow-up: source review before reusing
|
||||||
|
service-group APIs reproduced acceptance of `net-kingdom-admins` and
|
||||||
|
`net-kingdom-users`. The reserved prefix covered `netkingdom-` (suspension) but
|
||||||
|
omitted the actual hyphenated platform namespace. Both ensure and revoke now
|
||||||
|
reject `net-kingdom-` before directory login, including mixed service/platform
|
||||||
|
requests and delete-if-empty. Six new regressions fail on prior source; provider
|
||||||
|
suite and source hash evidence: Custodian
|
||||||
|
`docs/evidence/2026-10-14-netkingdom-security/platform-group-boundary.json`.
|
||||||
|
This is a provider source repair, not deployed enforcement or evidence of past
|
||||||
|
exploitation. The existing service-group behavior and tenant lifecycle remain
|
||||||
|
covered by their tests. Deploy/admit this source through the existing owner path
|
||||||
|
before treating the live boundary as fixed; native enforcement remains in T03.
|
||||||
|
|
||||||
## Verify owner-approved recovery and current native callers
|
## Verify owner-approved recovery and current native callers
|
||||||
|
|
||||||
```task
|
```task
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue