Skip to content

Add SafeSkill security badge (88/100 — Passes with Notes) - #1

Open
OyaAIProd wants to merge 1 commit into
spuentesp:mainfrom
OyaAIProd:safeskill-scan-1778551579656
Open

Add SafeSkill security badge (88/100 — Passes with Notes)#1
OyaAIProd wants to merge 1 commit into
spuentesp:mainfrom
OyaAIProd:safeskill-scan-1778551579656

Conversation

@OyaAIProd

Copy link
Copy Markdown

⚠️ SafeSkill Security Scan Results

Metric Value
Overall Score 88/100 (Passes with Notes)
Code Score 93/100
Content Score 77/100
Findings 74 findings detected (11 critical)
Taint Flows 0
Files Scanned 2
Scan Duration 0.4s

Top Findings

  • 🔴 critical: Imports child_process module (npm-shim/bin/lain.js:6)
  • 🔴 critical: Spawns child process (npm-shim/bin/lain.js:20)
  • 🔴 critical: Requires child_process module "child_process" (npm-shim/bin/lain.js:6)
  • 🔴 critical: Spawns child process: spawn() (npm-shim/bin/lain.js:20)
  • 🟡 medium: Imports filesystem module (npm-shim/bin/lain.js:7)

View full report on SafeSkill


About SafeSkill

SafeSkill is a free, open-source security scanner for AI tools, MCP servers, and Claude Code skills. We scan for code exploits, prompt injection, and data exfiltration risks.

False positive? We take accuracy seriously. If any finding above is incorrect, please open an issue and we will fix it immediately.

Signed-off-by: SafeSkill Scanner <mk@oya.ai>
spuentesp added a commit that referenced this pull request Aug 19, 2026
P0 #1 from the post-plan gap analysis: 'auth/rate-limit' (gate
producto). Previously the HTTP transport was open to any IP that
reached the port — no auth, no rate limit. An attacker could
register_agent with any name, claim files, and manipulate the
state. An LLM in a tight loop could saturate the server.

This commit adds:

- src/server/auth.rs: new module with AuthState (Bearer API key +
  token-bucket rate limit) and BearerToken + RateLimit helpers.
  Five unit tests cover the auth + rate-limit contract.
- src/server/ingest/mod.rs: LainServer gains an 'auth: Arc<AuthState>'
  field, populated from env at server startup (LAIN_API_KEYS,
  LAIN_RATE_LIMIT_RPM, LAIN_RATE_LIMIT=off).
- src/server/mcp/handler.rs: the HTTP request path now does an
  auth + rate-limit check before any other routing. /health is
  exempt (operational probe). 401 on missing/invalid bearer; 429
  with Retry-After header on rate-limit exceeded. Stdio transport
  bypasses this entirely.
- tests/auth_integration.rs: 8 runtime integration tests
  (bearer parsing, dev mode, multi-key acceptance, rate-limit
  per-key bucketing, refill timing, disable semantics).
- tests/federation_integration.rs: pre-existing test expected the
  pre-040cdd6 behavior (BeyondCurrent → empty changed_symbols).
  Updated to match the post-040dd6 contract (Retracted entries
  preserved across the error path).

Env vars:
  LAIN_API_KEYS=key1,key2,key3  comma-separated
  LAIN_RATE_LIMIT_RPM=60         default; set 0 to disable
  LAIN_RATE_LIMIT=off            explicit disable

If LAIN_API_KEYS is unset, AuthState is in dev mode: every
request passes auth (no rate limit either if not configured).
Stdio transport (Claude Code, Cursor, etc.) is exempt from both
since the agent process is local.

Verification:
- 13/13 smoke6 assertions against a live HTTP server in 4
  scenarios: dev mode (no env), auth on + /health exempt,
  per-key rate-limit bucketing, LAIN_RATE_LIMIT=off override.
- 8/8 auth_integration integration tests in cargo test.
- 568 lib + 16 federation_integration (after 1 updated) + 8
  auth_integration + all other binaries 0 failures.

Total tools: still 64 (no new MCP surface; auth is a transport
gate, not a tool). The product is now safe to expose on a network
without rate-limit-vulnerability to a misbehaving LLM loop.
spuentesp added a commit that referenced this pull request Aug 19, 2026
Resolves the gap analysis ask '_meta.revision en todas las read
tools' (P1 #1). Previously only the overlay's monotonic
counter was exposed on the JSON-RPC envelope. Agents using read tools
could not tell how fresh the static graph was without a separate
list_repos round-trip.

This commit adds  alongside
 on every  envelope (stdio and HTTP paths):

  - The stdio path's  calls  with
     where the value is
     — Unix epoch seconds
    of the most recent successful re-index start, or  when the
    re-index is skipped / failed / timed out.

  - The HTTP path's  closure builds the envelope
    inline (its own  literal) and was also updated to inject
    the same field. Both paths read the value once per dispatch so
    it is stable for the duration of the response.

  - The value is also cached in tests/static_graph_meta.rs as 5
    integration tests covering skipped / ok / failed / timeout
    outcomes, plus a 'fresh server starts skipped' sanity check.

Verification:
  - 5/5 integration tests pass.
  - 568 lib + 16 federation + 8 auth + 32 + others = 0 failures.
  - Live HTTP server: GET list_repos returns
    {_meta: {revision: 0, static_graph_generation: null}} on fresh
    boot and {revision: N, static_graph_generation: <ts>} after
    request_reload.
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.

1 participant