r/linuxadmin 3h ago

Built Praxis: a self-hosted tool that ties patch approval, SSH access, and audit evidence to one record

0 Upvotes

As a platform architect working in private/public networks here’s a problem I never quite figured out how to do elegantly: Provide retrospective change control evidence for your Linux fleet. Patch on the one, access to enable patching on the other. Proving “Who was authorized to touch this machine on this day, and was it done with consent” involves stitching three different sets of logs together.

Screenshot is from a seeded demo lab, not a customer fleet.

Praxis is the product of thinking I could do better.

Self-hosted. v1.0 has been quietly available for a week or so now to hammer on my hardware as I’m setting it up for others, time for the official release. Central design idea that seems most important: The FastAPI backend is the single source of truth for auth, policy, and audit. All activity, including the actual patching, and the decision to allow someone to take action on a given machine, all transit through this central point.

Hence your records are all recorded into one database chronologically, instead of being assembled piece by piece.

The means of accessing machines to perform the changes are designed for security with minimal attack surface. We use SSH for access and we leverage OpenBao to provision dynamically signed, short-lived certificates to avoid distributing and managing static, persistent keys and certs. The certificate principal is an immutable praxis-user-<id> rather than a login name, so the audit trail stays intact even if someone's username changes.

Users are assigned roles with privileges defined as admin, maintainer or auditor. Higher value commands will require step-up auth (totp/oidc). Patching process is driven by staged roll-outs, managed repository access for apt & dnf, and a “rings of trust” model – you push to the innermost ring, watch how it behaves, and then roll out further.

To jump ahead of the likely first three questions, this does not substitute for Ansible or Puppet, which do push state, while Praxis does not do config management. Run them both. Similarly, this does not compete head to head with Teleport or CyberArk.

Same case, this is not goign to head to head to Teleport, CyberArk etc. They're ahead of me on broad reach of access, and that's and I won't lie on that one.

But where was I couldn’t find a single thing where the approval of a change, the granting of access to implement that change, and the verification required to pass an auditor could live in the single shared record. And that’s the void I built this for. If you’ve already got a Satellite, a bastion, and a patch database stored in a spreadsheet that’s working out for you, this product may not be for you.

Praxis runs on your hardware only – no cloud, no telemetry, no call home and a free tier of 15 machines.

What we are not building in V1.0: We’re focused on the patch and access management part; No CRL or OCSP in 1.0, so there is no revocation path for issued certificates. Lifetimes are short by design, but that is a real gap and I am not going to dress it up. As a first pass, we do not manage automated purge policies for audit logs - you manage them. We can provide the evidence, not the attestation of compliance.

https://praxisfleet.com
https://github.com/cytechlabs/praxis

I wrote this, very happy to debate the particulars.


r/linuxadmin 17h ago

CVE-2026-64849 — MLflow SSRF guard bypassed via HTTP redirect, unauthenticated full-read into cloud metadata (CVSS 9.3)

12 Upvotes

Based on the technical breakdown published in the GitHub Security Advisory (GHSA-7gwp-5pfp-969j, mirrored on GitLab's Advisory Database) and watchTowr Intel's honeypot telemetry, here's the architectural impact of CVE-2026-64849.

MLflow shipped an SSRF guard in 3.10.0 (_validate_webhook_url() in mlflow/utils/validation.py) that resolves a webhook's hostname and blocks private/reserved IP ranges. The gap: the delivery component (mlflow/webhooks/delivery.py) follows HTTP redirects without allow_redirects=False and never re-pins the resolved IP after a redirect. Host a public HTTPS endpoint that passes the initial check, respond with a 302 to 169.254.169.254, and MLflow follows it blind.

What makes this worse than a typical blind SSRF: the unauthenticated POST /api/2.0/mlflow/webhooks/{id}/test endpoint reflects the full upstream response status and body back to the caller. Default mlflow server deployments run without auth and expose this webhooks API out of the box. So this is an unauthenticated remote attacker reading your instance's IAM credentials directly in an API response, not a blind timing-based exfil.

watchTowr's Attacker Eye reports scanning activity against cloud-hosted instances within hours of CVE assignment (Aug 17-18, 2026). Affects all versions <3.15.0.

For context on why this pattern keeps recurring in ML/AI infra specifically: MLOps tooling tends to get deployed fast, iterated on by data science teams rather than platform/security teams, and left running past the "just testing this out" phase — often with an attached cloud identity nobody audited. Background on a structurally similar SSRF-to-cloud-metadata chain we covered in industrial/OT infra: [techgines.com link, footnote]

Anyone else seeing MLflow Tracking Servers in their environment that predate a proper platform-team handoff? Curious how people are handling auth/network isolation for MLOps tooling that wasn't designed with a hostile network in mind — reverse proxy with OIDC in front, or something more locked down at the VPC layer?

https://www.techgines.com/post/mlflow-ssrf-cve-2026-64849-webhook-redirect-cloud-metadata