Skip to content

apiserver: accept a bouncer whose auto-created row a concurrent request inserted - #4775

Open
somaz94 wants to merge 1 commit into
crowdsecurity:masterfrom
somaz94:fix-bouncer-create-race
Open

somaz94 wants to merge 1 commit into
crowdsecurity:masterfrom
somaz94:fix-bouncer-create-race

Conversation

@somaz94

@somaz94 somaz94 commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor

What and why

When bouncers share one API key and the first two requests from a new IP arrive at the same time, both miss SelectBouncerWithIP and both try to create the name@ip row. The loser got a unique constraint error from CreateBouncer, and authPlain answered 403 for a valid key; authTLS had the same pattern. CreateBouncer now returns a typed BouncerExistsError on that error, with the same message so cscli bouncers add output does not change, and both paths re-read the row the other request just created and authenticate against it. A row with that name but another key, or an API key row on the TLS path, is still rejected.

Fixes #4774

How it was tested

I read the diff line by line. Claude Code ran the checks below while I watched, and I checked their output.

TestAPIKeyMiddlewareAutoCreatedBouncer uses an ent hook to insert the row right before the middleware creates it, on the API key and the TLS path, plus the two cases that must still be rejected. On master the two concurrent cases fail with bouncer test@4.3.2.1 already exists and a 403; with this change all six pass.

$ go test -run TestAPIKeyMiddlewareAutoCreatedBouncer -v ./pkg/apiserver/middlewares/v1/
    --- PASS: .../api_key,_new_ip
    --- PASS: .../api_key,_new_ip,_row_created_concurrently
    --- PASS: .../api_key,_name_taken_concurrently_by_another_key
    --- PASS: .../tls,_new_ip
    --- PASS: .../tls,_new_ip,_row_created_concurrently
    --- PASS: .../tls,_name_taken_concurrently_by_an_api_key_bouncer
ok  	github.com/crowdsecurity/crowdsec/pkg/apiserver/middlewares/v1	0.439s
$ TEST_LOCAL_ONLY=1 go test ./pkg/database/... ./pkg/apiserver/...   # all ok
$ golangci-lint run ./pkg/apiserver/middlewares/... ./pkg/database/   # v2.13.2
0 issues.

The Windows Build + tests job (TestStreamingAcquisitionMTLS timeout in pkg/acquisition/modules/http) and hub / Functional tests (socket path too long) fail the same way on master.

Checklist

  • One concern only.
  • No break to LAPI/CAPI payloads, database schema, config keys, or cscli -o json|raw output.
  • A human has reviewed this diff line by line.
  • A human has tested this change, not only an agent.

AI assistance used: mostly

@github-actions

Copy link
Copy Markdown

@somaz94: There are no 'kind' label on this PR. You need a 'kind' label to generate the release automatically.

  • /kind feature
  • /kind enhancement
  • /kind refactoring
  • /kind fix
  • /kind chore
  • /kind dependencies
Details

I am a bot created to help the crowdsecurity developers manage community feedback and contributions. You can check out my manifest file to understand my behavior and what I can do. If you want to use this for your project, you can check out the BirthdayResearch/oss-governance-bot repository.

@github-actions

Copy link
Copy Markdown

@somaz94: There are no area labels on this PR. You can add as many areas as you see fit.

  • /area agent
  • /area local-api
  • /area cscli
  • /area appsec
  • /area security
  • /area configuration
Details

I am a bot created to help the crowdsecurity developers manage community feedback and contributions. You can check out my manifest file to understand my behavior and what I can do. If you want to use this for your project, you can check out the BirthdayResearch/oss-governance-bot repository.

@somaz94

somaz94 commented Oct 23, 2026

Copy link
Copy Markdown
Contributor Author

/kind fix
/area local-api

@codecov

codecov Bot commented Oct 23, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 72.23%. Comparing base (725b665) to head (4ad0325).

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #4775      +/-   ##
==========================================
+ Coverage   71.82%   72.23%   +0.41%     
==========================================
  Files         545      527      -18     
  Lines       37163    36526     -637     
==========================================
- Hits        26691    26384     -307     
+ Misses      10471    10141     -330     
  Partials        1        1              
Flag Coverage Δ
bats 45.29% <44.44%> (-0.01%) ⬇️
unit-linux 50.03% <88.88%> (+0.25%) ⬆️
unit-windows ?

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ 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.

@somaz94
somaz94 marked this pull request as ready for review October 23, 2026 09:31

This branch has not been deployed

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

LAPI returns 403 when a bouncer's first two requests from a new IP race on auto-creating name@ip

1 participant