Skip to content

Add expired_tls_hotel_reservation problem - #784

Merged
Saadmrp1038 merged 3 commits into
SREGym:mainfrom
gAngelov24:feature/expired-tls-hotel-reservation
May 29, 2026
Merged

Saadmrp1038 merged 3 commits into
SREGym:mainfrom
gAngelov24:feature/expired-tls-hotel-reservation

Conversation

@gAngelov24

Copy link
Copy Markdown
Contributor

Real-World Failure

An expired TLS certificates are an extremely common cause of system outages. Unlike most failures, they are completely predictable since every certificate has a know expiry date; however, they still manage to take down major services. I previously mentioned in issue #763 some large cases where this has happened.

How I Simulated The Failure

The fault is injected into the Hotel Reservation app on its hotel-reservation namespace. The simulation required two additional Kubernetes resources:

  1. The Expired Certificate
    • The fault injector generates a new certificate at injection time using Python's cryptography library. At first I thought to use OpenSSL to generate the certificate however that library is strict about the date you set and wouldn't allow me to create an already expire certificate.
    • I also initially thought to write the certificate to the disk to avoid complex base64 string encoding, but I changed my implementation to base64 simply to keep everything local.
  2. Frontend Ingress
    • I added a new Kubernetes Ingress resource (frontend-ingress) which is applied to the namespace. It references the expired secret via the standard Kubernetes TLS Ingress configuration.

Like I stated above, I used Pythons cryptography package to generate the expired x509 certificate, and to parse the tls.crt PEM bytes from the Kubernetes Secret in order to read the not_valid_after_utc.
In order to use it I ran:

uv add cryptography

If not installed, both the inject_fault and the oracle's _get_cert_expiry methods log an ImportError with the fix command rather than producing a confusing traceback.

Problem Runtime

After the inject_fault() runs, the cluster has the following observable state:
Kubernetes resources:

kubectl get ingress -n hotel-reservation
NAME               CLASS   HOSTS         ADDRESS   PORTS     AGE
frontend-ingress   nginx   hotel.local             80, 443   Xs
 
kubectl describe ingress frontend-ingress -n hotel-reservation
# Shows: TLS terminates with secret "expired-frontend-cert"
# Annotation: nginx.ingress.kubernetes.io/ssl-redirect: "true"
 
kubectl get secret expired-frontend-cert -n hotel-reservation
NAME                    TYPE                DATA   AGE
expired-frontend-cert   kubernetes.io/tls   2      Xs

Certificate:

kubectl get secret expired-frontend-cert -n hotel-reservation \
  -o jsonpath='{.data.tls\.crt}' | base64 -d | openssl x509 -noout -dates
notBefore=<10 days ago>
notAfter=<1 day ago>

Pod health:

kubectl get pods -n hotel-reservation
# All pods show Running/Ready

HTTPS Behaviour:

  • Requests to https://hotel.local result in a failed TLS handshake
  • the NGINX Ingress controller logs chow certificate validation errors
  • HTTP requests are redirected to HTTPS (because of ssl-redirect: "true" in frontend-ingress) so there are no unencrypted fallback paths. Any path will be affected.

The challenge for an AI agent is that at first glance everything seems to be working:

  1. kubectl get pods -A shows all green
  2. Application logs show no errors at the app layer since TLS is terminated at the Ingress.
  3. Service/Deployment configs don't show anything abnormal

In order to find the underlying issue, the agent must specifically inspect the Ingress TLS configuration then cross reference the secret, and finally decode and inspect the certificate inside the secret.

Oracle Behavior

Before I get into Agent behavior, I want to talk about the new Oracle I had to design in order for this failure to work as expected. The default MitigationOracle checks pod health, which in this case is always fine since the expired TLS certificate does not affect pod health.
Therefore I made ExpiredTlsMitigationOracle to inspect the frontend Ingress at submission time and checks the expiry of any TLS secret it references. It will accept any of the following as valid mitigations: deleting the Ingress, deleting the secret, removing the TLS block from the Ingress, or replacing the secret with a valid certificate.
It will reject the submission if any referenced secret still contains an expired certificate.
I tested it in both cases:

  • submit() with failure active: success: false, "Secret 'expired-frontend-cert' still contains a certificate that expired on <timestamp>"
  • submit() after removing the Ingress and secret: success: true, "frontend-ingress has been deleted — mitigation accepted"

The Agent Behavior

Human Agent (me):

While I may have had some insider information about the problem, I was able to diagnose the issue and resolve it. I ran the following command to diagnose the failure:

kubectl get ingress -n hotel-reservation

This showed me the frontend-ingress referencing the expired-frontend-cert you could then inspect the cert to verify it is expired. Then I ran:

kubectl delete ingress frontend-ingress -n hotel-reservation
kubectl delete secret expired-frontend-cert -n hotel-reservation

This way I deleted the Ingress and secret to mitigate the failure.

AI Agent (Stratus, gemini/gemini-3.1-flash-lite)

The AI agent failed both stages across multiple attempts. During diagnosis, it checked the Jaeger for telemtry traces, found none, and submitted an incorrect root cause about services not sending data to Jaeger. Then, during mitigation, the agent read the frontend logs and found connection refused errors from the frontend trying to reach Consul. These errors are normal and go away on their own. It spent all 20 steps investing this error and never ran kubectl get ingress -n hotel-reservation
Note: Testing was also attempted with gemini/gemini-2.5-flash but hit the free-tier rate limit (5 RPM, 20 RPD). gemini/gemini-3.1-flash-lite was used for all completed runs.

Additional Change

Outside of the actual problem, I noticed that whenever I pressed enter without a prompt in the CLI, it would crash. I added a check that way anytime you press enter, whether on accident or not, the CLI doesn't just crash. If that was a feature and not a bug let me know I will remove that addition.

/validate-problem expired_tls_hotel_reservation

- Added expired_tls_hotel_reservation.py which is the main python script that simulates the expired TLS failure
- Added a new mitigation oracle since the default MitigationOracle was insufficient for this failure
- Updated registry.py to reflect the new problem added to the benchmark
- fixed small issue in cli.py which caused the command line interface to crash whenever 'enter' was pressed with no additional text
@Saadmrp1038

Copy link
Copy Markdown
Collaborator

@gAngelov24 Thanks for the PR! I will try to review it by tomorrow.

If that was a feature and not a bug let me know I will remove that addition.

Definitely a bug. Good catch!

@Saadmrp1038
Saadmrp1038 self-requested a review May 26, 2026 20:07
@Saadmrp1038 Saadmrp1038 added the problem Adding a new problem to the benchmark label May 26, 2026

@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.

@gAngelov24 Thanks for the effort! I left some comments below.

I am not sure if this fault is working correctly right now. The major issue I found is that IngressNginx().deploy() is missing from inject_fault.

the NGINX Ingress controller logs chow certificate validation errors

What controller did you mean by this? I don't think one is getting deployed currently. There is no ingress-nginx namespace or any Ingress controller running in the cluster.

Requests to https://hotel.local result in a failed TLS handshake

I wasn't able to reproduce this either. hotel.local doesn't resolve, and without a running Ingress controller, nothing is serving TLS on that hostname.

Can you please share the commands you used to test these claims and the logs they're based on? Not sure if I am missing something here.


Feel free to ping us if you have any questions or confusions!

Comment thread sregym/conductor/problems/manifests/frontend_ingress.yaml Outdated
Comment thread sregym/conductor/problems/expired_tls_hotel_reservation.py Outdated
Comment thread sregym/conductor/oracles/expired_tls_mitigation_oracle.py Outdated
Comment thread sregym/conductor/problems/expired_tls_hotel_reservation.py
Comment thread sregym/conductor/problems/expired_tls_hotel_reservation.py
Comment thread sregym/conductor/problems/expired_tls_hotel_reservation.py
Comment thread sregym/conductor/problems/manifests/frontend_ingress.yaml Outdated
@gAngelov24
gAngelov24 force-pushed the feature/expired-tls-hotel-reservation branch from 8f443d4 to 4a436dd Compare May 29, 2026 17:26
@gAngelov24

Copy link
Copy Markdown
Contributor Author

Okay, I addressed all the issues you had commented on. I changed variable names to be more realistic, I made the oracle inherit from the base oracle, and I fixed the fault so that NGINX controller reads the expired certificate.
I ran these commands:
Terminal 1:

uv run python cli.py
SREGym> start expired_tls_hotel_reservation

Terminal 2:

openssl s_client -connect localhost:8443 -servername hotel-reservation.local 2>&1 | openssl x509 -noout -dates -subject
kubectl logs -n ingress-nginx deployment/ingress-nginx-controller

Now, you should be able to see that the certificate being used by the NGINX is expired. The openssl command should output something like this:

notBefore=May 19 16:54:30 2026 GMT
notAfter=May 28 16:54:30 2026 GMT
subject=CN = hotel-reservation.local

The notAfter date in the past proves the expired cert is being served to clients rather than the NGINX default fallback.
You can also confirm the controller detects it with:
kubectl logs -n ingress-nginx deployment/ingress-nginx-controller
And look for:
SSL certificate for server "hotel-reservation.local" expired (2026-05-28 ...)
TLS handshake error from 10.244.0.1:15450: remote error: tls: bad certificate

@Saadmrp1038

Copy link
Copy Markdown
Collaborator

@gAngelov24 Thanks for addressing my comments! The fault is working correctly now.
Congrats on completing the eval task 🎉


Also, @gAngelov24 and @gAngel28 I got confused for a moment XD

@Saadmrp1038
Saadmrp1038 merged commit d0ef8a6 into SREGym:main May 29, 2026
6 checks passed
@tianyin

tianyin commented May 29, 2026

Copy link
Copy Markdown
Contributor

WoW!! This is awesome! Congrats!!

@Saadmrp1038

Saadmrp1038 commented May 29, 2026 •

Copy link
Copy Markdown
Collaborator

On a side note, agents really suffer in this problem. They get lost in the app namespace chasing random stuff and never checks the ingress-nginx-controller. I had to tweak the prompt to get the agent to notice the TLS error logs in the ingress-nginx namespace. But once it noticed the error it quickly fixed it (generated new valid cert). It does reveal a major flaw in our current agentic flow. The agents don't systematically explore outside the app namespace even when "everything looks healthy" in the app-namesapce and ideally it should broaden the search.

@tianyin

tianyin commented May 29, 2026

Copy link
Copy Markdown
Contributor

@Saadmrp1038 I feel you have so much materials to write another research paper :))

It does reveal a major flaw in our current agentic flow. The agents don't systematically explore outside the app namespace even when "everything looks healthy" in the app-namesapce and ideally it should broaden the search.

Bingo!

ermias19 pushed a commit to ermias19/SREGym that referenced this pull request Jun 5, 2026
* Add expired_tls_hotel_reservation problem

- Added expired_tls_hotel_reservation.py which is the main python script that simulates the expired TLS failure
- Added a new mitigation oracle since the default MitigationOracle was insufficient for this failure
- Updated registry.py to reflect the new problem added to the benchmark
- fixed small issue in cli.py which caused the command line interface to crash whenever 'enter' was pressed with no additional text

* Fix: add IngressNginx deploy, fix secret name, fix oracle inheritance

---------

Co-authored-by: Saad Mohammad Rafid Pial <saadmrp222@gmail.com>
ermias19 pushed a commit to ermias19/SREGym that referenced this pull request Jun 5, 2026
* Add expired_tls_hotel_reservation problem

- Added expired_tls_hotel_reservation.py which is the main python script that simulates the expired TLS failure
- Added a new mitigation oracle since the default MitigationOracle was insufficient for this failure
- Updated registry.py to reflect the new problem added to the benchmark
- fixed small issue in cli.py which caused the command line interface to crash whenever 'enter' was pressed with no additional text

* Fix: add IngressNginx deploy, fix secret name, fix oracle inheritance

---------

Co-authored-by: Saad Mohammad Rafid Pial <saadmrp222@gmail.com>
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.

4 participants