Conversation
Docs:
- The configuration reference described `PROFILER_AUTH_TOKEN` through `oxphp_profiler_*` PHP functions, of which the product has none — the userland API is `OxPHP\Profile\*`, and that prefix belongs to Prometheus metrics and internal symbols — and it put the token in front of enabling profiling from PHP, where it has never stood. The row now names what it does gate (the three explicit triggers, the bearer on the `/__profiler/*` routes), what an unset or empty value means for each, and that neither sampling nor the PHP functions consult it. An operator who set the token and read the old row expected `runs_total{source="sdk"}` to count only requests carrying it; it counts every one.
Tests:
- Pin the sampling half of that claim. The two existing sample-rate tests run with no token configured, so nothing held sampling to ignoring one — a token check moved ahead of the draw would have left them green.
1718 unit tests, 1864 with the integration binaries.
diolektor
deleted the
fix/profiler-auth-token-row-names-php-functions-that-do-not-exist
branch
September 20, 2026 13:56
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
The
PROFILER_AUTH_TOKENrow indocs/operations/configuration.mdread:Two errors in one row, both present in the released 0.11.0 text.
There is no
oxphp_profiler_*PHP function. The userland API is seven functions in theOxPHP\Profilenamespace (src/plugins/ox_profiler/php_sdk.rs:32,48,68,77,85,95,111). Theoxphp_profiler_prefix belongs to Prometheus metric names and internal C/Rust symbols — 88 hits repo-wide, not one of them a PHP function, and no near-miss spelling (oxphp_profile*,profiler_start) exists either. This row was the only place indocs/that presented the prefix as userland PHP. The neighbouringoxphp_apm_*()row is not the same mistake: those functions really are flat (src/plugins/ox_apm/php_sdk.rs), and the profiler row looks like that template applied to a namespaced API.The token does not stand in front of the PHP functions.
register_functionstakes_enabledand never reads it (php_sdk.rs:21-28); registration runs atmod.rs:390, ahead of theif !self.enabledgate at:438; andOxPHP\Profile\start()reads neither config nor headers. The token is consulted in exactly two places:validate_tokenfor the three explicit triggers (trigger.rs:124-138) and the bearer check on the internal server's/__profiler/*routes (routes.rs:71-86).What that costs a reader: searching their own code for
oxphp_profiler_*returns nothing, and believing the token closes PHP-side activation means treating an open door as closed — set the token, andruns_total{source="sdk"}still counts every request whose script callsstart(), not only the ones carrying it.What the row says now
Three things were added beyond removing the false names. The unset-or-empty behaviour, because
config.rs:91-97collapses both toNone, after whichvalidate_tokenaccepts any non-empty trigger value andcheck_authdemands no bearer — the old row said only "when set" and left the other side of the branch to guesswork. The two non-gates, because the second error was an attributed gate, and naming the real ones without denying the false one leaves the reader's wrong belief intact. And thePROFILER_ENABLED=truequalifier on the SDK clause: a first draft promisedstart()profiles its own request unconditionally, which is not so —initreturns before installing the request-end observer, the run store and the routes when the master switch is off, while the SDK functions are registered earlier and unconditionally, so calls succeed and collect nothing.Wording follows
docs/features/profiling.md:222, which already stated this correctly, rather than inventing a third formulation.Guard
The diff adds no branch, so most of the row is verified by reading and by tests that already exist:
trigger.rs::test_token_required_and_correct,_incorrect,_length_mismatch_rejectedtest_header_activates_without_token,_cookie_,_query_/__profiler/*demands a bearer when a token is setprofiler_routes_tests::auth_enforced_on_stats_when_token_configuredtests/php/profiler/test_source_sdk.php, which runs underPROFILER_AUTH_TOKEN=test-tokenwith no trigger and assertsstart()profiled the requestThat last row is why this PR carries a test. Both existing sample-rate tests run with
auth_token = None, so nothing held sampling to ignoring a configured token: a token check moved ahead of the draw would have left them green while making the new sentence false.test_sample_rate_ignores_a_configured_tokenconfigures a token, sends a request carrying no trigger at all, and asserts the activation source is stillSampleRate. Mutant check: insertingif cfg.auth_token.is_some() { return None; }before the sampling branch reddens exactly this test and leaves the two existing ones passing.What is deliberately not touched
The
PROFILER_INTERNALrow directly above it. It is separately wrong, but fixing it needs a product decision about what the knob is supposed to mean, and that does not belong in a one-row correction.§17 of
docs/features/profiling.mdstill does not say that an unset token accepts any non-empty trigger value. The new row says it on the configuration page; the feature page's own hardening section is a wider change than this.One pre-existing divergence is worth flagging for whoever reviews the last clause, since that clause rides on it:
PROFILER_ENABLEDis parsed by the Rust boolean parser (on/true/1/yes, case-insensitive) when the plugin boots, butext/oxphp_sapi.c:7513-7519registers the observer only on a case-sensitive"true"or"1".PROFILER_ENABLED=yestherefore boots the plugin, answers the routes, reports enabled on/config, and collects no span. Tracked separately, untouched here.Verification
cargo fmt -- --check,cargo clippy --no-default-features -- -D warnings— cleancargo test --no-default-features, and withplugin-apm,plugin-async,plugin-profiler,plugin-shared— 1718 unit, 1864 including the integration binaries, 0 failedscripts/gen-llms-txt.sh && scripts/gen-llms-txt.sh --check— up to date (58 pages);llms-full.txtis regenerated, and its diff is the same single linegrep -rn 'oxphp_profiler_'over the repo — 88 hits, all metric names or internal symbols;grep -rn PROFILER_AUTH_TOKEN docs/ README.md CHANGELOG.md src/— every remaining description names the same gates as the new row