You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix: exempt /metrics /healthz /readyz from auth; numeric UID in Dockerfile (#148)
* feat(connector): Stripe, Okta, Shopify, Mailchimp, OneDrive, QuickBooks, and RabbitMQ connectors
Adds 17 new connector actions across 7 services:
- stripe/create_charge, stripe/create_customer, stripe/create_refund
- okta/list_users, okta/create_user
- shopify/list_orders, shopify/list_products, shopify/create_order
- mailchimp/list_members, mailchimp/add_member
- onedrive/upload, sharepoint/list_items
- quickbooks/create_invoice, quickbooks/list_invoices
- rabbitmq/publish, rabbitmq/consume
Also adds parseJSONBody shared helper to tools.go and
github.com/rabbitmq/amqp091-go v1.11.0 as the AMQP protocol client.
Closes#94, #108, #109, #111, #112, #114, #115
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(connector): address Codex review comments on OneDrive and RabbitMQ
- OneDrive: remove url.PathEscape on filePath to preserve literal "/"
separators in Graph API path templates (escaping produced %2F which
resolved to a file literally named "documents%2Fhello.txt")
- RabbitMQ: ack each message inside the consume loop when auto_ack=false
so messages are not requeued when the channel closes on return
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(connector): address CodeRabbit review on saas-connector batch
- rabbitmq: validate params before dialing (exchange/routing_key/body for
publish, queue for consume) so invalid requests fail without a connection
- rabbitmq: use amqp.DialConfig with net.Dialer.DialContext so the dial
respects context cancellation
- rabbitmq: default auto_ack=false (at-least-once); true opts into at-most-once
- onedrive: add escapePath helper to encode individual path segments without
escaping "/" separators, so nested folders work with Graph path addressing
- onedrive_test: assert request URL path to catch future slash-escaping regressions
- quickbooks: reject where/order_by values that contain structural keywords
(maxresults, startposition, orderby) to prevent clause injection
- shopify: extract shopifyAPIURL package-level helper, removing three identical
apiURL methods
- go.mod: go mod tidy promotes amqp091-go from indirect to direct
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix: exempt /metrics, /healthz, /readyz from auth; numeric UID in Dockerfile
- server: register /metrics, /healthz, and /readyz on a top-level mux so
Kubernetes probes and Prometheus scrapers bypass API key auth entirely.
All other routes fall through to the auth/rate-limit-wrapped apiMux.
- Dockerfile: create the mantle user with explicit -u 10001 -g 10001 and
switch to USER 10001:10001 so kubelet can verify runAsNonRoot: true
without a numeric runAsUser override in the Helm chart.
Closes#139Closes#137
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(connector): Okta activate param, Mailchimp upsert endpoint
Okta: always pass ?activate=<bool> — omitting it when false causes Okta
to activate the user by default, triggering unintended provisioning side effects.
Mailchimp: switch add_member from POST /members to PUT /members/{hash}
(MD5 of lowercased email). The POST endpoint returns a duplicate-member
error on reruns; the PUT upsert endpoint is idempotent.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(connector): suppress gosec/CodeQL false positives on Mailchimp MD5
The Mailchimp subscriber hash is MD5(lowercase(email)) per Mailchimp's
own API specification — it is a lookup identifier, not a security hash.
Add inline suppression annotations for both gosec G401 and CodeQL
go/weak-sensitive-data-hashing to clarify the non-security intent.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(connector): correct gosec nosec placement for Mailchimp MD5
G501 fires on the import line and G401 on the call site — both need
their own same-line #nosec annotations. The combined //nolint+#nosec
format wasn't parsed correctly by gosec.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(connector): add CodeQL inline suppression for Mailchimp MD5
Add CodeQL[go/weak-sensitive-data-hashing] inline suppression alongside
the gosec #nosec annotation. The earlier attempt used lowercase 'codeql'
which GitHub Code Scanning does not recognize — the exact token is
'CodeQL[rule-id]' (capital C, Q, L).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(connector): CodeQL suppression for Mailchimp MD5 (standalone comment)
Use standalone // CodeQL[go/weak-sensitive-data-hashing] on the
preceding line as GitHub docs specify — no other text on that line.
Also add .github/codeql/codeql-config.yml as a fallback that excludes
the go/weak-sensitive-data-hashing query for the connector package.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(server): move /metrics behind auth to prevent workflow name leakage
Prometheus path labels include workflow names (via metricsMiddleware →
normalizePath). Serving /metrics on the unauthenticated top-level mux
let anyone enumerate workflow identifiers without credentials. Moved
/metrics to apiMux so it goes through the same auth middleware as all
other API routes. Health probes (/healthz, /readyz) remain on the
unauthenticated mux for Kubernetes probe access.
Prometheus scrapers must now supply an API key.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Michael McNees <mmcnees@Michaels-MacBook-Pro.local>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
0 commit comments