Skip to content

Add admission webhook TLS mismatch problem - #777

Merged
Saadmrp1038 merged 2 commits into
SREGym:mainfrom
mohamedharake:admission-webhook-tls-mismatch
May 26, 2026
Merged

Add admission webhook TLS mismatch problem#777
Saadmrp1038 merged 2 commits into
SREGym:mainfrom
mohamedharake:admission-webhook-tls-mismatch

Conversation

@mohamedharake

@mohamedharake mohamedharake commented May 24, 2026

Copy link
Copy Markdown
Contributor

Adds a new SREGym problem simulating an admission-webhook TLS trust mismatch in the Hotel Reservation app. The failure is a production-style Kubernetes admission-control issue: the webhook backend is reachable, but the ValidatingWebhookConfiguration contains a stale/wrong caBundle, so the kube-apiserver rejects pod CREATE requests with an x509 verification error.

The PR is limited to the new problem plus registry wiring.


1. The real-world failure story

Admission webhooks sit directly in the Kubernetes API request path. If a ValidatingWebhookConfiguration has failurePolicy: Fail, then matching requests are rejected whenever the webhook call fails. This is risky because the affected application can be healthy, but Kubernetes may still be unable to create replacement pods.

This problem models a certificate-rotation / CA-drift failure: the webhook backend is reachable and serving HTTPS, but the caBundle stored in the ValidatingWebhookConfiguration is stale or wrong. The kube-apiserver therefore cannot verify the webhook server certificate and rejects pod CREATE admission requests with an x509 error.

Several real-world reports anchor this simulation:

The SREGym scenario keeps the same failure class but makes it reproducible: the backend exists and is reachable, while the trust relationship between the kube-apiserver and webhook is intentionally broken.


2. How the failure is simulated in SREGym

The new problem class lives at:

sregym/conductor/problems/admission_webhook_tls_mismatch.py

and is registered as:

admission_webhook_tls_mismatch_hotel_reservation

The fault injection does the following:

  1. Creates a temporary policy-system namespace.
  2. Generates TLS material:
    • one CA that signs the webhook server certificate,
    • a separate wrong CA used as the stale caBundle.
  3. Deploys a small HTTPS webhook backend as policy-system/pod-policy-webhook.
  4. Installs a ValidatingWebhookConfiguration named pod-policy.validation.k8s.io.
  5. Scopes the webhook to the target app namespace using namespaceSelector.
  6. Configures the webhook with:
    • failurePolicy: Fail
    • pod CREATE admission rules
    • the reachable webhook service
    • the intentionally wrong caBundle
  7. Deletes one pod from the recommendation deployment so the ReplicaSet has to recreate it.

The recreate attempt then hits the webhook and fails during TLS verification.


3. Problem runtime behaviour

Verified locally through the SREGym CLI and Kubernetes events.

Phase Observation
App deploy Hotel Reservation deploys normally before fault injection
Backend setup policy-system/pod-policy-webhook is created as a reachable HTTPS service
Fault injection recommendation pod is deleted
Symptom recommendation ReplicaSet has desired=1, current=0, ready=0
Diagnostic signal ReplicaSet events show failed calling webhook with an x509 certificate error
Blast radius Scoped to hotel-reservation through namespaceSelector
Recovery Deleting the broken webhook allows the ReplicaSet to recreate the missing pod

The key event observed locally:

failed calling webhook "pod-policy.validation.k8s.io":
tls: failed to verify certificate:
x509: certificate signed by unknown authority

This is the main diagnostic signal an agent should follow. The pod is not failing because of its own image, command, memory, or service config; pod creation is being rejected by admission control.


4. Mitigation and validation

Valid mitigations:

  • delete the broken ValidatingWebhookConfiguration,
  • patch failurePolicy from Fail to Ignore,
  • or repair the webhook trust chain by restoring the correct caBundle.

Local mitigation test used the first path:

kubectl delete validatingwebhookconfiguration pod-policy.validation.k8s.io

After that, the ReplicaSet recreated the missing recommendation pod and the SREGym mitigation oracle passed.

Local final result:

Check Result
Problem starts Passed
Fault injection Passed
Runtime symptom recommendation under-replicated
Expected event x509: certificate signed by unknown authority observed
Mitigation oracle Passed
Diagnosis judge Skipped locally because JUDGE_MODEL_ID was not configured

5. Expected agent behaviour

I have not run Stratus end-to-end on this problem yet.

Expected successful agent path:

  1. Notice recommendation is under-replicated.
  2. Inspect the ReplicaSet / events instead of only checking the application pod logs.
  3. Find that pod creation is failing at admission time.
  4. Identify the cluster-scoped ValidatingWebhookConfiguration.
  5. Distinguish a TLS trust mismatch from a missing webhook backend.
  6. Mitigate by deleting the webhook, changing failurePolicy, or repairing caBundle.

The intended challenge is that the visible symptom is application-level availability loss, but the root cause is a cluster-scoped admission-control dependency.


Notes for reviewers

  • No new Python package dependency is added.
  • The webhook backend is created dynamically as a small Python HTTPS server.
  • The failure is scoped to the target app namespace using namespaceSelector.
  • Recovery deletes both the webhook configuration and the temporary policy-system namespace.
  • Currently only the Hotel Reservation variant is registered; sibling variants for social_network or astronomy_shop can be added if useful.

@mohamedharake

Copy link
Copy Markdown
Contributor Author

Hi, I opened this PR for the evaluation task.

It adds a new SREGym problem that simulates an admission webhook TLS trust mismatch caused by a stale/wrong caBundle. I tested it locally: the fault produces a failed calling webhook / x509: certificate signed by unknown authority error, and mitigation succeeds by deleting the broken ValidatingWebhookConfiguration.

I’d appreciate any feedback.

@Saadmrp1038 Saadmrp1038 added the problem Adding a new problem to the benchmark label May 24, 2026
@Saadmrp1038
Saadmrp1038 self-requested a review May 24, 2026 13:43
@Saadmrp1038

Copy link
Copy Markdown
Collaborator

@mohamedharake Thanks for the PR! Could you please write a more detailed/structured PR description? It would help me greatly in reviewing it. Some points you can include:

  • The real-world failure story -- what incident or outage inspired this scenario?
  • How you simulate the failure in SREGym -- what mechanisms, fault injection, or config changes are used?
  • The problem runtime behavior -- what does the system look like when the failure is active? (symptoms, metrics, logs, etc.)
  • Agent behavior (if possible) -- how does an agent (Stratus or other agents) respond to this fault?

You can use these PRs as reference:

  1. Add service wrong pod selection benchmark for Hotel Reservation #757
  2. Add admission_webhook_outage_hotel_reservation problem #758

@mohamedharake

Copy link
Copy Markdown
Contributor Author

Thank you so much for the feedback. I updated the PR description with the real world failure story, simulation details, runtime behavior, mitigation/testing notes, and expected agent behavior. I’ll also try running Stratus now and add the results if I can get it working locally.

@Saadmrp1038

Saadmrp1038 commented May 24, 2026

Copy link
Copy Markdown
Collaborator

@mohamedharake Thank you! There are quite a few PRs I have to review. I'll try to get to this one as soon as I can.

@Saadmrp1038 Saadmrp1038 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mohamedharake This is a great PR! Very clean implementation. I tested the fault and everything works nicely.
There's just this one small nit. Ping me when it's done. I will merge the PR!

Comment on lines +108 to +124
self._run(["openssl", "genrsa", "-out", str(ca_key), "2048"], stdout=subprocess.DEVNULL)
self._run([
"openssl", "req", "-x509", "-new", "-nodes",
"-key", str(ca_key),
"-sha256", "-days", "365",
"-subj", "/CN=sregym-real-webhook-ca",
"-out", str(ca_crt),
], stdout=subprocess.DEVNULL)

self._run(["openssl", "genrsa", "-out", str(wrong_ca_key), "2048"], stdout=subprocess.DEVNULL)
self._run([
"openssl", "req", "-x509", "-new", "-nodes",
"-key", str(wrong_ca_key),
"-sha256", "-days", "365",
"-subj", "/CN=sregym-stale-wrong-ca",
"-out", str(wrong_ca_crt),
], stdout=subprocess.DEVNULL)

@Saadmrp1038 Saadmrp1038 May 25, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Let's use generic/realistic names here for /CN. I don't like to use names that can reveal internal information to the agent.
For example, when running with claudecode it read this data:

The root cause is clear now:\n\n1. The CA  bundle in the `ValidatingWebhookConfiguration` (`pod-policy.validation.k8s.io`) contains a CA with CN = `sregym-stale-wrong-ca`\n2. The server certificate in the `pod-policy-webhook-tls` secret was signed by a CA  with CN = `sregym-real-webhook-ca`

@Saadmrp1038

Copy link
Copy Markdown
Collaborator

On a side note, I ran this problem with multiple agents. The mitigation by Claude Code was very interesting. Instead of taking a shortcut (deleting the webhook), it successfully repaired the trust chain by generating a new CA, signing a new server cert, and patching both the TLS secret and the webhook's caBundle to match.

@mohamedharake

Copy link
Copy Markdown
Contributor Author

Done, thanks a lot! I renamed the certificate common names to more generic/realistic values.
Also that Claude Code mitigation is really interesting. Thank you for testing it with multiple agents. I really appreciate the review and feedback.

@Saadmrp1038

Copy link
Copy Markdown
Collaborator

@mohamedharake Awesome! Congrats on your first PR merged here 🎉
Keep up the good work!

@Saadmrp1038
Saadmrp1038 merged commit d9d38d9 into SREGym:main May 26, 2026
4 of 5 checks passed
@tianyin

tianyin commented May 26, 2026

Copy link
Copy Markdown
Contributor

This is great work!!

@mohamedharake

Copy link
Copy Markdown
Contributor Author

Thank you!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

problem Adding a new problem to the benchmark

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants