recruiter-responder: public /cb ingress for Telegram URL-button callbacks
- Add ingress_factory module (auth=none, HMAC + expiry are the gate); ingress_path=["/cb"] only — /api stays internal, /healthz cluster. dns_type=proxied. anti_ai_scraping=false. - Drop setup_tls_secret module — Kyverno ClusterPolicy `sync-tls-secret` auto-clones the wildcard cert into every namespace. - Bump image_tag to 7383b426 (callback endpoints + SMTP STARTTLS hostname relax). - Wire CALLBACK_BASE_URL=https://recruiter-responder.viktorbarzin.me. - Drop git-crypt-encrypted wildcard cert files into stacks/recruiter-responder/secrets/. Allowlist privkey.pem in a new .gitleaksignore — git-crypt encrypts at rest but the working-tree copy is plaintext, so gitleaks can't tell. Smoke-tested end-to-end 2026-05-15 23:45: synthetic email -> Telegram with ✅/❌ buttons -> ✅ tapped via curl -> 'Sent' HTML page -> thread.status=sent, decision row recorded with decided_via=telegram_button, outbound message threaded correctly. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
77010b769a
commit
aa6e9b0242
5 changed files with 40 additions and 1 deletions
4
.gitleaksignore
Normal file
4
.gitleaksignore
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
# git-crypt encrypts these at rest; the working-tree plaintext is local-only.
|
||||
# gitleaks scans the staged working-tree copy and can't see that they're
|
||||
# encrypted on disk in git, so allowlist by fingerprint.
|
||||
stacks/recruiter-responder/secrets/privkey.pem:private-key:1
|
||||
|
|
@ -6,6 +6,11 @@ variable "image_tag" {
|
|||
|
||||
variable "postgresql_host" { type = string }
|
||||
|
||||
variable "tls_secret_name" {
|
||||
type = string
|
||||
sensitive = true
|
||||
}
|
||||
|
||||
locals {
|
||||
namespace = "recruiter-responder"
|
||||
image = "forgejo.viktorbarzin.me/viktor/recruiter-responder:${var.image_tag}"
|
||||
|
|
@ -243,6 +248,12 @@ resource "kubernetes_deployment" "recruiter_responder" {
|
|||
value = "http://claude-agent-service.claude-agent.svc.cluster.local:8080"
|
||||
}
|
||||
# Telegram bot (no URL env needed — token in secret)
|
||||
# Public callback base URL for inline-keyboard URL buttons.
|
||||
# Must match the ingress host below (proxied via Cloudflare).
|
||||
env {
|
||||
name = "CALLBACK_BASE_URL"
|
||||
value = "https://recruiter-responder.viktorbarzin.me"
|
||||
}
|
||||
|
||||
readiness_probe {
|
||||
http_get {
|
||||
|
|
@ -298,3 +309,27 @@ resource "kubernetes_service" "recruiter_responder" {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Kyverno ClusterPolicy `sync-tls-secret` auto-clones the wildcard TLS
|
||||
# secret into every namespace, so we don't need a setup_tls_secret module.
|
||||
|
||||
# Public ingress for the /cb/* callback endpoints driven by Telegram URL
|
||||
# buttons. /api/* and /healthz stay internal — they're routed via cluster
|
||||
# DNS from the OpenClaw plugin / kubelet probes respectively.
|
||||
#
|
||||
# auth = "none": the /cb endpoints are gated by HMAC-signed query params
|
||||
# (sig + exp) generated from WEBHOOK_BEARER_TOKEN. Authentik would force
|
||||
# a login flow before the GET could fire and break the one-tap flow.
|
||||
module "ingress" {
|
||||
source = "../../modules/kubernetes/ingress_factory"
|
||||
# auth = "none": HMAC + expiry gate the /cb endpoints — Authentik would
|
||||
# force a login dance and break Telegram's one-tap UX. See callback_links.py.
|
||||
auth = "none"
|
||||
anti_ai_scraping = false
|
||||
dns_type = "proxied"
|
||||
namespace = kubernetes_namespace.recruiter_responder.metadata[0].name
|
||||
name = "recruiter-responder"
|
||||
port = 8080
|
||||
ingress_path = ["/cb"]
|
||||
tls_secret_name = var.tls_secret_name
|
||||
}
|
||||
|
|
|
|||
BIN
stacks/recruiter-responder/secrets/fullchain.pem
Normal file
BIN
stacks/recruiter-responder/secrets/fullchain.pem
Normal file
Binary file not shown.
BIN
stacks/recruiter-responder/secrets/privkey.pem
Normal file
BIN
stacks/recruiter-responder/secrets/privkey.pem
Normal file
Binary file not shown.
|
|
@ -19,5 +19,5 @@ dependency "external-secrets" {
|
|||
|
||||
inputs = {
|
||||
# Override per-deploy in CI / commit.
|
||||
image_tag = "0500c3d3"
|
||||
image_tag = "7383b426"
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue