Skip to content

Support optional anonymous authentication#114

Merged
kylehounslow merged 4 commits intoopensearch-project:mainfrom
lezzago:Anonymous-auth
Mar 20, 2026
Merged

Support optional anonymous authentication#114
kylehounslow merged 4 commits intoopensearch-project:mainfrom
lezzago:Anonymous-auth

Conversation

@lezzago
Copy link
Member

@lezzago lezzago commented Mar 19, 2026

Summary

Adds optional anonymous authentication for OpenSearch and OpenSearch Dashboards, controlled by a single .env toggle (OPENSEARCH_ANONYMOUS_AUTH). This makes it easy to skip the login page for demos, workshops, or shared development environments.

  • New .env variable: OPENSEARCH_ANONYMOUS_AUTH=false (default off, set to true to enable)
  • OpenSearch security config: New config.template.yml, roles.yml, and roles_mapping.yml define the anonymous role with read access to all indices and limited write access to Dashboards system indices (needed for UI settings persistence)
  • OpenSearch Dashboards config: Template updated to inject anonymous_auth_enabled and disable savedObjects.permission.enabled so anonymous users can access workspaces created by the init script
  • Init script: Sets defaultWorkspace so all users (including anonymous) land directly in the Observability Stack workspace; adds anonymous role to Prometheus datasource allowedRoles
  • Documentation: Updated README, docker-compose README, AGENTS.md, and installation docs with usage instructions, security notes, and troubleshooting guidance

How it works

  1. OPENSEARCH_ANONYMOUS_AUTH is read from .env and injected via sed at container startup into two templates:
    • config.template.yml → OpenSearch security plugin config
    • opensearch_dashboards.template.yml → Dashboards config
  2. Custom roles.yml grants anonymous users read access everywhere plus index/update/bulk (but not delete) on Dashboards system indices
  3. roles_mapping.yml maps the anonymous backend role to the custom role
  4. Toggling the setting requires docker compose down -v because OpenSearch applies security config to an internal index on first startup

Anonymous user permissions

Action Allowed
Browse data (traces, logs, metrics) Yes
View/create/modify dashboards, visualizations, saved queries Yes
Explore trace analytics and service maps Yes
Run PPL and SQL queries Yes
Access REST API without credentials Yes
Delete existing saved objects No
Write data to indices No
Admin operations (security, cluster settings) No

Why modify access? Dashboards persists UI settings on every page load via update/bulk writes to system indices. Without these permissions, pages fail with 403 errors. Since UI settings and saved objects share the same indices, this also allows modification of existing saved objects.

Test plan

  • Start stack with OPENSEARCH_ANONYMOUS_AUTH=false (default) — verify login page appears and credentials are required
  • Set OPENSEARCH_ANONYMOUS_AUTH=true, run docker compose down -v && docker compose up -d — verify Dashboards loads without login
  • As anonymous user: browse traces, logs; create and modify a dashboard; verify delete is blocked
  • Toggle back to false, restart with -v — verify login page returns and previously created objects are preserved
  • Verify admin user still has full access in both modes

Screenshots

Anonymous auth - Dashboards view Anonymous auth - Workspace view

Issues Resolved

N/A

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
For more information on following Developer Certificate of Origin and signing off your commits, please check here.

lezzago added 2 commits March 19, 2026 13:37
Signed-off-by: Ashish Agrawal <ashisagr@amazon.com>
Signed-off-by: Ashish Agrawal <ashisagr@amazon.com>
@codecov
Copy link

codecov bot commented Mar 19, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 18.51%. Comparing base (3233e6f) to head (866f99d).
⚠️ Report is 4 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main     #114   +/-   ##
=======================================
  Coverage   18.51%   18.51%           
=======================================
  Files           3        3           
  Lines          54       54           
  Branches       19       19           
=======================================
  Hits           10       10           
  Misses         44       44           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Signed-off-by: Ashish Agrawal <ashisagr@amazon.com>
@lezzago lezzago changed the title Anonymous auth Support optional anonymous authentication Mar 19, 2026
@lezzago lezzago added the enhancement New feature or request label Mar 19, 2026
@lezzago lezzago marked this pull request as ready for review March 19, 2026 23:25
@kylehounslow
Copy link
Collaborator

Note: This review was generated by Claude (via Kiro CLI) on behalf of @kylehounslow.

PR #114 Review: Support optional anonymous authentication

Overall: This is a well-structured, well-documented feature. The single-toggle design via .env is the right call for a dev-oriented quickstart repo. The PR description is one of the best I've seen — clear permissions matrix, honest about tradeoffs, good test plan. That said, I have several concerns ranging from security to operational correctness.


🔴 Must-fix (blocking)

1. savedObjects.permission.enabled: false is unconditional — it applies even when anonymous auth is OFF.

This is the biggest issue. The Dashboards template sets savedObjects.permission.enabled: false regardless of the OPENSEARCH_ANONYMOUS_AUTH value. When anonymous auth is disabled (the default), this still disables workspace-level permission checks for all authenticated users. That's a security regression for the default configuration.

This should be conditional — either use a second sed placeholder that's toggled based on the anonymous auth flag, or template it so it's true when anon is off and false when anon is on. Alternatively, make it another sed replacement tied to the same env var with inverted logic in the startup command.

2. docker compose down -v as the only toggle mechanism destroys all data.

The PR docs say "Any saved objects created by anonymous users are preserved and remain accessible to authenticated users after disabling anonymous auth." This is contradicted by the requirement to use -v which nukes all volumes. You can't have it both ways. Either:

  • Use the Security Admin API (securityadmin.sh) to hot-reload security config without volume deletion, or
  • Be honest in the docs that toggling this setting is destructive and all data is lost

The current docs are misleading. At minimum, fix the documentation to remove the claim about preserved saved objects.

3. roles.yml replaces the entire default roles file.

The comment says "Reserved/static roles are built into the security plugin and remain available." This is true, but mounting a custom roles.yml that only defines the anonymous role means any non-reserved custom roles that might exist in the default roles.yml are silently dropped. For this repo it's probably fine today, but it's a landmine. Add a comment in the file explicitly stating this replaces the default and listing what's lost, or better yet, only mount these files when OPENSEARCH_ANONYMOUS_AUTH=true using a conditional volume mount approach.


🟡 Should-fix (non-blocking but important)

4. sed placeholder collision risk in config.template.yml.

The placeholder OPENSEARCH_ANONYMOUS_AUTH is a bare string in the YAML: anonymous_auth_enabled: OPENSEARCH_ANONYMOUS_AUTH. If someone sets the env var to anything other than true or false (e.g., empty string, yes, 1), the resulting YAML will be invalid or have unexpected behavior. Add input validation in the startup command:

if [ "${OPENSEARCH_ANONYMOUS_AUTH}" != "true" ]; then export OPENSEARCH_ANONYMOUS_AUTH=false; fi

5. Duplicate sed line in docker-compose.local-opensearch-dashboards.yml.

There's a duplicate sed -i 's|OPENSEARCH_USER|...|g' line (appears twice). This is harmless but sloppy — the second invocation is a no-op since the first already replaced all occurrences. Remove the duplicate.

6. allowedRoles on Prometheus datasource hardcodes opendistro_security_anonymous_role.

In init-opensearch-dashboards.py, the Prometheus datasource allowedRoles changed from [] to ["all_access", "opendistro_security_anonymous_role"]. This means even when anonymous auth is disabled, the datasource is configured to reference a role that may not be mapped to any user. It's harmless but conceptually wrong — the init script should check OPENSEARCH_ANONYMOUS_AUTH and conditionally include the anonymous role. The all_access addition is also a behavior change that should be called out.

7. tenant_permissions grants kibana_all_write on '*' (all tenants).

The comment explains why, but this is broader than necessary. For a dev quickstart it's acceptable, but worth noting that in any multi-tenant scenario this would be a significant privilege escalation. Consider scoping to just the global tenant if possible.


🟢 Nits / suggestions

  1. The roles_mapping.yml file wasn't visible in the diff (GitHub rendering issue). Verify this file is present and correct.

  2. Documentation is thorough but repetitive. The anonymous auth section is explained in README.md, docker-compose/README.md, AGENTS.md, and the installation docs. Consider having one canonical section and linking to it from the others to reduce maintenance burden.

  3. The PR closes issue [DOCS] Improve onboarding flow for Agent Developer persona #113 ("Improve onboarding flow for Agent Developer persona"). The connection between anonymous auth and onboarding improvement should be made more explicit — why does skipping login improve the agent developer onboarding flow specifically?

  4. set_default_workspace() is a good addition that benefits all users, not just anonymous ones. Consider calling this out as a standalone improvement that could be a separate commit.


Summary

The architecture is sound — single env var toggle, template-based injection, least-privilege role design with a well-reasoned exception for Dashboards system indices. The main issues are: (1) the unconditional savedObjects.permission.enabled: false is a security regression for the default config, (2) the docs contradict the destructive nature of down -v, and (3) input validation on the env var is missing. Fix those three and this is ready to ship.

# but cannot delete existing saved objects or perform admin operations
# Modify access is required — Dashboards persists UI settings via update/bulk writes on page load
# Set OPENSEARCH_ANONYMOUS_AUTH=true in .env to enable
opensearch_security.auth.anonymous_auth_enabled: OPENSEARCH_ANONYMOUS_AUTH
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: rename to OPENSEARCH_ANONYMOUS_AUTH_ENABLED to better match config name

Copy link
Member Author

Choose a reason for hiding this comment

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

lol, claude suggested it from that to this due to how other values were named. Will change it back.

By default, users must log in to access OpenSearch Dashboards. To skip the login page (useful for demos or workshops), enable anonymous authentication in `.env`:

```env
OPENSEARCH_ANONYMOUS_AUTH=true
Copy link
Collaborator

Choose a reason for hiding this comment

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

same nit re: name above. apply across all files

Signed-off-by: Ashish Agrawal <ashisagr@amazon.com>
payload = {
"name": datasource_name,
"allowedRoles": [],
"allowedRoles": ["all_access", "opendistro_security_anonymous_role"] if ANONYMOUS_AUTH_ENABLED else ["all_access"],
Copy link
Collaborator

Choose a reason for hiding this comment

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

should this be if OPENSEARCH_ANONYMOUS_AUTH_ENABLED?

Copy link
Collaborator

Choose a reason for hiding this comment

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

nvm I see this set at L18, please disregard

@kylehounslow kylehounslow merged commit b5aeed7 into opensearch-project:main Mar 20, 2026
10 checks passed
lezzago added a commit to lezzago/observability-stack that referenced this pull request Mar 22, 2026
Reverts:
- 3155afe fix: rename OPENSEARCH_ANONYMOUS_AUTH to OPENSEARCH_ANONYMOUS_AUTH_ENABLED in .env (opensearch-project#115)
- b5aeed7 feat: Support optional anonymous authentication (opensearch-project#114)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
lezzago added a commit to lezzago/observability-stack that referenced this pull request Mar 22, 2026
Reverts:
- 3155afe fix: rename OPENSEARCH_ANONYMOUS_AUTH to OPENSEARCH_ANONYMOUS_AUTH_ENABLED in .env (opensearch-project#115)
- b5aeed7 feat: Support optional anonymous authentication (opensearch-project#114)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Ashish Agrawal <ashisagr@amazon.com>
kylehounslow pushed a commit that referenced this pull request Mar 22, 2026
Reverts:
- 3155afe fix: rename OPENSEARCH_ANONYMOUS_AUTH to OPENSEARCH_ANONYMOUS_AUTH_ENABLED in .env (#115)
- b5aeed7 feat: Support optional anonymous authentication (#114)

Signed-off-by: Ashish Agrawal <ashisagr@amazon.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants