Add HTTP Basic authentication to the Yamcs action for proxied servers - #1447
Merged
Conversation
Ground segments commonly publish Yamcs through a reverse proxy, such as Apache, that challenges every request with HTTP Basic authentication against a directory before the request reaches Yamcs. Yamcs behind that proxy often has no authentication of its own. The Yamcs action could authenticate to Yamcs but had no way to answer a front-door proxy challenge, so such a server was unreachable even when every Yamcs setting was correct. Adds an optional Reverse Proxy Authentication layer, independent of the Yamcs authentication method and off by default so a directly reachable server, such as a local simulator, is unaffected. Credentials can be entered inline, with the password stored in Key Vault, or supplied by a reusable username/password identity. The proxy credential gets its own identity reference, separate from the Yamcs credential, so one action can use both and a rotating temporary password is maintained once under Workspace > Identities instead of by editing the action. Proxy Basic auth combines with the none and api_key Yamcs methods. It is blocked for username_password and bearer_token: only one Authorization header can be sent, and the Yamcs token exchange would itself be refused by the proxy. The rule is enforced in the plugin, the health checker, the test-connection route, and the action modal, so the conflict surfaces before an agent depends on it. Implementation notes: - yamcs-client 2.1.0 already ships BasicAuthCredentials, so no dependency change is needed. It is imported separately from the other credential classes so a deployment on an older client keeps working for every non-proxy method. - basic_auth_password is registered in YAMCS_SENSITIVE_ADDITIONAL_FIELDS, which routes it through the existing Key Vault store, redact, retrieve, and delete handling. - The proxy identity reference is resolved inside validate_action_identity_reference and hydrate_action_identity_reference, so personal, group, and global action paths pick it up unchanged. UI hydration returns the identity username but never its password. - Turning the toggle off preserves the stored credential rather than blanking it, which would drop the Key Vault reference and orphan the secret. Fixes #1435 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
8 tasks
… through an exception' Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
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.
Summary
Linked issue
Fixes #1435
Release Notes & Latest Features
Is this visible to end users?
Is this admin-facing (Admin Settings, governance, deployment, config)?
Should this become a Latest Feature card?
Screenshot needed for the card?
Version bump
application/single_app/config.pyVERSIONthird segment bumped, or not needed because this is docs-onlydeployers/version.txtbumped, or not needed becausedeployers/was not changedVERSIONis0.261.012. This branch was rebased ontoDevelopmentafter0.261.010and0.261.011shipped for the Azure Managed Redis work, so the version and release-notes section were re-numbered to avoid colliding with those releases.Design notes
yamcs-client==2.1.0is already pinned inrequirements.txtand shipsBasicAuthCredentials, so there is no dependency change. It is imported lazily and separately from the other credential classes, so a deployment running an older yamcs-client keeps working for every non-proxy auth method and only sees an actionable upgrade message when proxy auth is actually requested.Authentication compatibility
Only one HTTP
Authorizationheader can be sent, which makes two combinations genuinely impossible rather than merely unimplemented:BasicAuthCredentialspassed ascredentials=APIKeyCredentialsusesx-api-key, leavingAuthorizationfree for the proxyAuthorization, and the/auth/tokenrequest would itself be refused by the proxyAuthorizationThe rule is enforced in four places — the plugin,
PluginHealthCheckerat save time, the test-connection route, and the action modal — so the conflict surfaces before an agent depends on it.Identity refactor
The proxy reference is resolved inside
validate_action_identity_referenceandhydrate_action_identity_reference, so all existing personal, group, and global action call sites pick it up with no changes. UI (TRIGGER) hydration returns the identity username but never the password; runtime (VALUE) hydration resolves both.Testing / validation
functional_tests/test_yamcs_basic_auth.py— 12/12 (new)functional_tests/test_yamcs_action_plugin.py— 14/14 (unchanged, no regression)functional_tests/test_docs_app_surface_coverage.py— 7/7functional_tests/test_docs_site_quality.py— 6/6route_tests/test_route_blueprint_policy_inventory.py— 6/6; plus the unauthenticated-policy and policy-coverage route suitestest_action_workspace_identity_scoping.py::test_workspace_identity_action_helperswas confirmed identical on the baseline viagit stash.node --checkonplugin_modal_stepper.js;py_compileon every changed Python module; verified allfunctions_yamcs_operationsimports resolve across the four importing modules.Not validated: live connectivity against a real proxied Yamcs server, which needs the partner team's dev environment.
Documentation
Updated
docs/reference/actions/yamcs.md,docs/explanation/features/YAMCS_ACTION.md, anddocs/explanation/release_notes.md(plus the generated release-notes index).Security checklist
@swagger_route(security=get_auth_security())sanitize_settings_for_user()No new routes were added; the existing
test-yamcs-connectionroute already carries the decorator and keeps it.basic_auth_passwordis registered inYAMCS_SENSITIVE_ADDITIONAL_FIELDS, so it inherits the existing Key Vault store/redact/retrieve/delete handling, and the test-connection route resolves it withACTION_ADDITIONAL_SECRET_SOURCESscope enforcement. The password never reaches the browser, logs, or telemetry — only the booleanbasic_auth_enabledis logged.Known limitation
A reusable identity resolves within the workspace scope that owns the action, so a personal action paired with a personal identity gives each engineer their own credential. A single shared group action resolves one group-scoped credential rather than a distinct credential per member; per-user resolution at chat time would be a materially larger feature and is out of scope here.