Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -327,8 +327,14 @@ jobs:
# single-attachment volume: rolling tries to stand up a parallel
# machine and errors on the attachment slot. The agent group has
# no volume, but strategy is app-wide.
# --ha=false because Fly provisions TWO machines by default for
# a newly-declared process group. For `agent` that is actively
# wrong: two workers drain the same run queue, and POST /start
# is idempotent rather than exclusive, so both would claim the
# same run and we would pay for the LLM call twice. The first
# deploy of the agent group did exactly this.
echo "Releasing $IMAGE to sentinel-command"
flyctl deploy --image "$IMAGE" --strategy immediate --yes -a sentinel-command
flyctl deploy --image "$IMAGE" --strategy immediate --ha=false --yes -a sentinel-command

echo "--- process groups after release ---"
flyctl machines list -a sentinel-command --json \
Expand Down
22 changes: 20 additions & 2 deletions backend/app/sentinel_agent/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
the MCP server which org each tool call is on behalf of.
"""

from pydantic import field_validator, model_validator
from pydantic import AliasChoices, Field, field_validator, model_validator
from pydantic_settings import BaseSettings


Expand Down Expand Up @@ -80,7 +80,25 @@ class Settings(BaseSettings):
# The override header is still sent and is accepted as long as it
# names the key's own org.
opensentry_mcp_url: str = "" # derived from opensentry_api_base if blank
opensentry_mcp_agent_key: str = ""
# Reads OPENSENTRY_MCP_AGENT_KEY first, then Command Center's own
# SENTINEL_AGENT_MCP_KEY. The second alias exists because the agent
# now runs as a process group of the sentinel-command app and shares
# its environment — without it the hosted agent would need a
# duplicate copy of a secret that is already right there, under a
# different name.
#
# This matters more than tidiness: the first-party deployment uses
# two genuinely DIFFERENT shared secrets (run-queue vs MCP), so the
# self-hosted fallback below would quietly hand the MCP surface the
# wrong key — an agent that fetches work and then fails every tool
# call, which is exactly the failure that fallback was written to
# prevent for self-hosters.
opensentry_mcp_agent_key: str = Field(
"",
validation_alias=AliasChoices(
"OPENSENTRY_MCP_AGENT_KEY", "SENTINEL_AGENT_MCP_KEY"
),
)

# ── Webhook signature behaviour ──────────────────────────────────
# When False, /wakeup skips HMAC verification — useful for local
Expand Down