fix(recovery): distinguish malformed paths from outside-folder denial
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s

Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a13eab-1e6a-7b33-9c37-372e90ada3a2
This commit is contained in:
tegwick 2026-10-16 07:48:36 +02:00
parent a17aa7edc1
commit 72c598e7de
7 changed files with 470 additions and 2 deletions

View file

@ -409,3 +409,14 @@ no periodic capture/expiry is enabled by installation alone. One subsequent
OIDC attempt timed out before owner-command handoff; it did not run mutations,
and its possible session revocation was unconfirmed. Only the contained owner
login lane is retried, without switching to root or inspecting captured bytes.
The native publisher fixture subsequently proved read/create, denied overwrite
and delete, and exact fixture cleanup. Its malformed parent path was rejected
withHTTP400. The checker now records that separately and also requires a valid
outside-account-folder request to fail authentication; accepting a malformed
path rejection alone would not establish authorization confinement.16 provider
checks pass after this correction. A fresh metadata capture plan confirms zero
allow policies matching helper Pods. The next owner login timed out before
handoff; no corrected provider probe or KV/ESO publication ran in that attempt.
The installed runtime's timers remain disabled while attended admission resumes.

View file

@ -0,0 +1,380 @@
{
"schema": "netkingdom.identity-capture-plan.v1",
"status": "requires_owner_execution_admission",
"created_at": "2026-10-16T05:46:40.122854+00:00",
"run_id": "ba725bea599b",
"binding": {
"schema": "netkingdom.identity-backup-preparation.v1",
"status": "prepared_not_admitted",
"observed_at": "2026-10-16T05:46:39.447927+00:00",
"cluster_uid": "a553c742-0115-43d4-99a4-a5ca56fe0786",
"profile_sha256": "40f9e5b5bb957e5b23e03b31701702b850502d16a92a0fa0ebf92618cc3f18a1",
"source_sha256": "cd5f3067d28b4c7cc93ed08b8cf3869218bdecf7c54b5dffed22d697de71dbb1",
"bindings": [
{
"namespace": "sso",
"deployment": "lldap",
"uid": "743a86bd-5cb0-4ca0-9c56-a3438f4746a8",
"generation": 7,
"pvc_bindings": [
{
"name": "lldap-data",
"uid": "0a06b65a-e7b3-42d3-916e-e74dbe5fc7da"
}
],
"secret_names_only": [
"lldap-secrets"
],
"configmap_names_only": []
},
{
"namespace": "sso",
"deployment": "authelia",
"uid": "dc40a925-2306-4a3b-89c0-e714187503c3",
"generation": 28,
"pvc_bindings": [
{
"name": "authelia-data",
"uid": "86826554-b014-4df4-8b28-866aa64f6413"
}
],
"secret_names_only": [
"authelia-secrets",
"authelia-smtp"
],
"configmap_names_only": [
"authelia-config"
]
},
{
"namespace": "sso",
"deployment": "keycape",
"uid": "99ddd83c-cb3f-4847-bcf8-35f1aa87627f",
"generation": 65,
"pvc_bindings": [
{
"name": "keycape-authentication-policy",
"uid": "423f558f-8c11-4edf-956b-243559df4a8e"
}
],
"secret_names_only": [
"keycape-approval-engine-operator-client",
"keycape-config",
"keycape-factor-read",
"keycape-informed-decision-sitting-requester-client",
"keycape-rapp-qonto-client",
"keycape-secrets-engine-approval-client",
"keycape-secrets-engine-openbao-client",
"keycape-secrets-engine-requester-client"
],
"configmap_names_only": []
},
{
"namespace": "mfa",
"deployment": "privacyidea",
"uid": "58c7f96d-61cb-4dd4-bca2-54661c0ac375",
"generation": 11,
"pvc_bindings": [
{
"name": "privacyidea-data",
"uid": "65650fc1-02d8-4c0f-84fc-e0015c8f3ed9"
},
{
"name": "privacyidea-logs",
"uid": "39fa90d9-bc54-4a03-a0d6-ae85165e0cb9"
}
],
"secret_names_only": [
"privacyidea-config"
],
"configmap_names_only": [
"factor-recovery-01119187d90d7b76",
"keycape-onboarding-9465e5e0b98f7986",
"privacyidea-cfg"
]
}
],
"secret_values_read": false,
"backup_captured": false,
"uploaded": false,
"runtime_changed": false,
"credential_grant_created": false,
"owner_admission_required": [
"Approve exact CCR-2026-0048/0049 grants and node runtime packet; three required owner reviews, confirmed native SA/namespace/audience boundaries before acceptance",
"Exclude helper capture label from existing broad DNS allow policies; validate read-only helper manifests and cluster/PVC/source bindings before private capture",
"Preserve every referenced credential encrypted with original keys; fresh native SQLite/PG snapshots and exact manifest, with documented omissions and no global atomicity claim",
"Create fresh ciphertext and exact Storage Share object, read back ciphertext and receipt by strong ETag/hash, independently retrieve using operator custody",
"Attended independent age-key proof: wrong-key denial, complete archive hashes, SQLite/RSA checks, disposable native PostgreSQL restore and verified cleanup before timer activation",
"Full NK49 closure separately requires native directory/issuer/MFA authentication, retained token decryption, audit signature continuity, current callers and legacy credential dispositions; archive acceptance does not close those gates",
"Host-local health cannot report a dead host; external outage monitoring and second-provider copy remain separate coverage gaps"
]
},
"kubeconfig": "/home/worsch/.kube/config",
"sources": [
{
"path": "capture-identity.py",
"sha256": "47dca7c4dc96fa7eb9fb02c81fca9ca8dc5281aac918979eb7367148168ba705"
},
{
"path": "identity-files.py",
"sha256": "d0063a9eedd3610e3d45bd2d834aae83cff74e4b3504d138b3548f427e89331d"
},
{
"path": "identity-bundle.py",
"sha256": "524a03c065db4307fcde83d33af39503f3de19cb6ef3a8ca72c991d4a8c08ee6"
},
{
"path": "prepare-identity-coverage.py",
"sha256": "cd5f3067d28b4c7cc93ed08b8cf3869218bdecf7c54b5dffed22d697de71dbb1"
},
{
"path": "identity-backup-profile.json",
"sha256": "40f9e5b5bb957e5b23e03b31701702b850502d16a92a0fa0ebf92618cc3f18a1"
}
],
"database": {
"namespace": "databases",
"cluster": "net-kingdom-pg",
"cluster_uid": "0cd04a7c-a183-48ac-975a-9f244ea82c73",
"pod": "net-kingdom-pg-1",
"pod_uid": "0404c66b-338b-4446-a767-622d248ab0d3",
"database": "privacyidea_db"
},
"create_resources": [
{
"apiVersion": "networking.k8s.io/v1",
"kind": "NetworkPolicy",
"metadata": {
"name": "nk49-capture-ba725bea599b",
"namespace": "sso"
},
"spec": {
"podSelector": {
"matchLabels": {
"net-kingdom/capture": "ba725bea599b"
}
},
"policyTypes": [
"Ingress",
"Egress"
],
"ingress": [],
"egress": []
}
},
{
"apiVersion": "v1",
"kind": "Pod",
"metadata": {
"name": "nk49-capture-ba725bea599b",
"namespace": "sso",
"labels": {
"net-kingdom/capture": "ba725bea599b"
}
},
"spec": {
"restartPolicy": "Never",
"activeDeadlineSeconds": 900,
"automountServiceAccountToken": false,
"securityContext": {
"runAsUser": 0,
"runAsGroup": 0
},
"containers": [
{
"name": "capture",
"image": "ghcr.io/gpappsoft/privacyidea-docker@sha256:af7841adad262f129e0c1d4f553af13f21cb2f4dc713533f316cfe43ed0b4473",
"imagePullPolicy": "IfNotPresent",
"command": [
"python3",
"-c",
"import time; time.sleep(900)"
],
"securityContext": {
"allowPrivilegeEscalation": false,
"readOnlyRootFilesystem": true,
"capabilities": {
"drop": [
"ALL"
],
"add": [
"DAC_OVERRIDE"
]
}
},
"resources": {
"requests": {
"cpu": "50m",
"memory": "128Mi"
},
"limits": {
"cpu": "1",
"memory": "2Gi"
}
},
"volumeMounts": [
{
"name": "lldap",
"mountPath": "/source/lldap",
"readOnly": true
},
{
"name": "authelia",
"mountPath": "/source/authelia",
"readOnly": true
},
{
"name": "keycape",
"mountPath": "/source/keycape",
"readOnly": true
},
{
"name": "scratch",
"mountPath": "/scratch"
}
]
}
],
"volumes": [
{
"name": "lldap",
"persistentVolumeClaim": {
"claimName": "lldap-data",
"readOnly": true
}
},
{
"name": "authelia",
"persistentVolumeClaim": {
"claimName": "authelia-data",
"readOnly": true
}
},
{
"name": "keycape",
"persistentVolumeClaim": {
"claimName": "keycape-authentication-policy",
"readOnly": true
}
},
{
"name": "scratch",
"emptyDir": {
"medium": "Memory",
"sizeLimit": "512Mi"
}
}
]
}
},
{
"apiVersion": "networking.k8s.io/v1",
"kind": "NetworkPolicy",
"metadata": {
"name": "nk49-capture-ba725bea599b",
"namespace": "mfa"
},
"spec": {
"podSelector": {
"matchLabels": {
"net-kingdom/capture": "ba725bea599b"
}
},
"policyTypes": [
"Ingress",
"Egress"
],
"ingress": [],
"egress": []
}
},
{
"apiVersion": "v1",
"kind": "Pod",
"metadata": {
"name": "nk49-capture-ba725bea599b",
"namespace": "mfa",
"labels": {
"net-kingdom/capture": "ba725bea599b"
}
},
"spec": {
"restartPolicy": "Never",
"activeDeadlineSeconds": 900,
"automountServiceAccountToken": false,
"securityContext": {
"runAsUser": 0,
"runAsGroup": 0
},
"containers": [
{
"name": "capture",
"image": "ghcr.io/gpappsoft/privacyidea-docker@sha256:af7841adad262f129e0c1d4f553af13f21cb2f4dc713533f316cfe43ed0b4473",
"imagePullPolicy": "IfNotPresent",
"command": [
"python3",
"-c",
"import time; time.sleep(900)"
],
"securityContext": {
"allowPrivilegeEscalation": false,
"readOnlyRootFilesystem": true,
"capabilities": {
"drop": [
"ALL"
],
"add": [
"DAC_OVERRIDE"
]
}
},
"resources": {
"requests": {
"cpu": "50m",
"memory": "128Mi"
},
"limits": {
"cpu": "1",
"memory": "2Gi"
}
},
"volumeMounts": [
{
"name": "privacyidea",
"mountPath": "/source/privacyidea",
"readOnly": true
},
{
"name": "scratch",
"mountPath": "/scratch"
}
]
}
],
"volumes": [
{
"name": "privacyidea",
"persistentVolumeClaim": {
"claimName": "privacyidea-data",
"readOnly": true
}
},
{
"name": "scratch",
"emptyDir": {
"medium": "Memory",
"sizeLimit": "512Mi"
}
}
]
}
}
],
"service_changes": false,
"credential_grants": false,
"matching_network_allow_policies": [],
"network_policy_enforcement_requires_owner_confirmation": true,
"offsite_delivery_included": false,
"global_atomic_snapshot_claimed": false,
"finished_at": "2026-10-16T05:46:40.884474+00:00"
}

View file

@ -0,0 +1,24 @@
{
"status": "refused_malformed_parent_status_before_kv_publication",
"action": "publisher",
"caller_entity_id": "4a1f663c-0621-0483-edd0-f852274f4b6b",
"caller_auth_path": "auth/netkingdom/oidc/callback",
"quota_before": {
"quota_bytes": 10737418240,
"used_bytes": 7094108469,
"available_bytes": 3643309771
},
"folder_created": false,
"share_created": false,
"share_id": "26",
"share_permissions": 21,
"folder": "/railiance-backups/net-kingdom-identity",
"provider_test_artifacts": [
"nk49-boundary-b7c9df967f844454ba87fe73a5582bd8.age",
"nk49-boundary-7c9e4e216c124a1ea3178e56e63cce67.age"
],
"boundary_fixture_cleanup_verified": false,
"boundary_phase": "deny_parent_path",
"parent_probe_status": 400,
"owner_fixture_cleanup_verified": true
}

View file

@ -1,5 +1,5 @@
{
"status": "approved_native_provider_delivery_checks_in_progress",
"status": "runtime_installed_provider_admission_waiting_attended_login",
"observed_at": "2026-10-15T23:56:00.293983+00:00",
"approval_decision": "40bfae40-6108-4e51-8613-073339f5345f",
"approved_platform_source_commit": "69a792c",
@ -38,5 +38,14 @@
"focused_tests_passed": 52,
"temporary_dns_selector_exclusions_applied": true,
"network_policy_rule_lines_present": 649,
"installed_runtime_release": "bf8b38f185037515cfad9eebcddefc9f60ace724c32e10d89ae8307dc95a4eb7"
"installed_runtime_release": "bf8b38f185037515cfad9eebcddefc9f60ace724c32e10d89ae8307dc95a4eb7",
"current_login_session_active": false,
"latest_login_failure": "callback_timeout_before_handoff",
"latest_timeout_possible_session_revocation_confirmed": false,
"publisher_read_create_and_overwrite_delete_denial_verified": true,
"publisher_fixture_cleanup_verified": true,
"parent_path_rejection_status": 400,
"corrected_boundary_tests_passed": 16,
"corrected_native_boundary_and_delivery_not_yet_run": true,
"helper_network_allow_count": 0
}