Skip to content

ref(server): Skip auth checks when not configured#519

Open
jan-auer wants to merge 3 commits into
mainfrom
ref/optional-auth
Open

ref(server): Skip auth checks when not configured#519
jan-auer wants to merge 3 commits into
mainfrom
ref/optional-auth

Conversation

@jan-auer

Copy link
Copy Markdown
Member

Auth checks previously ran on every request regardless of server-side configuration, producing noisy warnings in environments without auth (e.g. local development). Auth is now skipped entirely when it is not configured — meaning no keys are present and enforcement is off (AuthZ::is_active()).

When auth is active, enforce controls whether failures reject the request (debug log) or just warn. AuthAwareService::new is now infallible since the "enforcement enabled but no context" error state is no longer reachable.

@jan-auer jan-auer requested a review from a team as a code owner June 24, 2026 17:20
@codecov

codecov Bot commented Jun 24, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 93.02326% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 87.40%. Comparing base (2cc842a) to head (1244e90).
⚠️ Report is 3 commits behind head on main.

Files with missing lines Patch % Lines
objectstore-server/src/auth/service.rs 91.66% 2 Missing ⚠️
objectstore-server/src/extractors/service.rs 91.66% 1 Missing ⚠️
Additional details and impacted files
@@           Coverage Diff           @@
##             main     #519   +/-   ##
=======================================
  Coverage   87.40%   87.40%           
=======================================
  Files          86       86           
  Lines       13893    13887    -6     
=======================================
- Hits        12143    12138    -5     
+ Misses       1750     1749    -1     
Components Coverage Δ
Rust Backend 92.28% <93.02%> (-0.01%) ⬇️
Rust Client 80.07% <ø> (+0.04%) ⬆️
Python Client 88.51% <ø> (ø)

☔ View full report in Codecov by Harness.
📢 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.

Comment thread objectstore-server/src/auth/service.rs
if !enforce {
objectstore_log::warn!(?permission, ?usecase, ?code, ?msg, "Auth failure");

if warn {

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

This moves the responsibility to decide on the log level to the caller, which actually carries the necessary info. It's a more appropriate place than on the error.

objectstore_log::warn!(?permission, ?usecase, ?code, ?msg, "Auth failure");

if warn {
objectstore_log::warn!(code, reason=%self, "Auth failure");

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Permission and usecase were only passed at a single place where they are available. Thus, we're now configuring them on the scope, removing two special-case parameters from this function's signature. The values are still available in the Sentry error.

Note that they won't be printed to stderr anymore, which we have not needed.

true => Ok(auth_result?),
false => Ok(()),
pub fn new(service: StorageService, context: Option<AuthContext>, enforce: bool) -> Self {
Self {

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

enforce && context.is_none() is no longer a valid state, but also the contract has changed:

  • the extractor still has the responsibility for validating this
  • context: None now is the primary argument and enforce only controls what happens when a context is provided.

The new doc comment above elaborates on this. Note that this is just the contract for AuthAwareService, not the public config!

/// Returns `Ok(())` if authorized, or an error indicating the reason.
pub fn check_permission(&self, perm: Permission, context: &ObjectContext) -> ApiResult<()> {
self.assert_authorized(perm, context)
if let Some(auth) = &self.context

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

This was inlined. Apparently, the assert_authorized method was intended to become public, but instead a plain wrapper created.

Comment on lines +24 to +26
if !state.config.auth.is_active() {
return Ok(AuthAwareService::new(state.service.clone(), None, enforce));
}

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

This is the main difference: If auth is inactive, we skip everything.

Everything below is equivalent to before and only refactored for readability / brevity.

/// configured. Without enforcement, authorization checks are still performed and reported but
/// failures will not result in `403 Unauthorized`
pub fn is_active(&self) -> bool {
self.enforce || !self.keys.is_empty()

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

This is because enforce defaults to true: We must activate auth also when there are no keys provided, so that the default config triggers auth failures.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants