Can Agents Run It? · evidence — Issue 1: Supabase

moonshotai/kimi-k3 · d2_webhooks · rep 2

pass
model
moonshotai/kimi-k3
task
d2_webhooks
rep
2
day
2
steps
8
tokens
21,584
est. cost
$0.162
agent time
219s
wave
s4
started
2026-07-24T14:52:10Z

The task as the agent received it

You have operator access to a hosted Supabase project. Credentials are in environment variables: SUPABASE_URL, SUPABASE_PROJECT_REF, SUPABASE_ANON_KEY, SUPABASE_SERVICE_ROLE_KEY, SUPABASE_DB_URL, SUPABASE_DB_PASSWORD. Every INSERT into the existing table public.signups must deliver an HTTP webhook: a POST request with a JSON body containing at least the new row's email and plan values, sent to the receiver endpoint {SUPABASE_URL}/functions/v1/hook-recorder (an edge function that is already deployed on this project; SUPABASE_URL is in your environment). The receiver requires a valid project JWT in the Authorization header and records every payload it accepts. Implement the delivery from the database itself, so it fires for ANY insert into signups no matter which client performs it — no external workers, no cron, no client-side code. Delivery may be asynchronous (a few seconds is fine). Prove it end-to-end with a test insert before finishing: the receiver stores accepted payloads in public.webhook_receipts.

What it ran — 8 commands

#1exit 0
env | grep -i supabase | sed 's/\(KEY=.\{20\}\).*/\1.../; s/\(PASSWORD=.\{6\}\).*/\1.../' ; echo "---"; which psql pg_isready
SUPABASE_DB_PASSWORD=1a9f7b...
SUPABASE_DB_URL=<redacted:SUPABASE_DB_URL>
SUPABASE_URL=https://<ref>.supabase.co
SUPABASE_SERVICE_ROLE_KEY=eyJhbGciOiJIUzI1NiIs...
SUPABASE_PROJECT_REF=<ref>
SUPABASE_ANON_KEY=eyJhbGciOiJIUzI1NiIs...
---
/usr/bin/psql
/usr/bin/pg_isready
#2exit 0
psql "$SUPABASE_DB_URL" -c "\dt public.*" -c "\d public.signups" -c "\d public.webhook_receipts"
                List of tables
 Schema |       Name       | Type  |  Owner   
--------+------------------+-------+----------
 public | signups          | table | postgres
 public | webhook_receipts | table | postgres
(2 rows)

                                     Table "public.signups"
   Column   |           Type           | Collation | Nullable |             Default              
------------+--------------------------+-----------+----------+----------------------------------
 id         | bigint                   |           | not null | generated by default as identity
 email      | text                     |           | not null | 
 plan       | text                     |           | not null | 'free'::text
 created_at | timestamp with time zone |           | not null | now()
Indexes:
    "signups_pkey" PRIMARY KEY, btree (id)

                                 Table "public.webhook_receipts"
   Column    |           Type           | Collation | Nullable |             Default              
-------------+--------------------------+-----------+----------+----------------------------------
 id          | bigint                   |           | not null | generated by default as identity
 received_at | timestamp with time zone |           | not null | now()
 payload     | jsonb                    |           | not null | 
Indexes:
    "webhook_receipts_pkey" PRIMARY KEY, btree (id)

#3exit 0
psql "$SUPABASE_DB_URL" -c "select name, default_version, installed_version from pg_available_extensions where name in ('pg_net','http','pg_cron','plpgsql') order by name;" -c "select extname, extversion from pg_extension order by 1;"
  name   | default_version | installed_version 
---------+-----------------+-------------------
 http    | 1.6             | 
 pg_cron | 1.6.4           | 
 pg_net  | 0.20.4          | 
 plpgsql | 1.0             | 1.0
(4 rows)

      extname       | extversion 
--------------------+------------
 pg_stat_statements | 1.11
 pgcrypto           | 1.3
 plpgsql            | 1.0
 supabase_vault     | 0.3.1
 uuid-ossp          | 1.1
(5 rows)

#4exit 0
echo "== no auth =="; curl -s -o /dev/null -w "%{http_code}\n" -X POST "$SUPABASE_URL/functions/v1/hook-recorder" -H "Content-Type: application/json" -d '{}'
echo "== anon JWT =="; curl -s -w "\n%{http_code}\n" -X POST "$SUPABASE_URL/functions/v1/hook-recorder" -H "Content-Type: application/json" -H "Authorization: Bearer $SUPABASE_ANON_KEY" -d '{"probe":"anon","email":"probe@example.com","plan":"probe"}'
echo "== service JWT =="; curl -s -w "\n%{http_code}\n" -X POST "$SUPABASE_URL/functions/v1/hook-recorder" -H "Content-Type: application/json" -H "Authorization: Bearer $SUPABASE_SERVICE_ROLE_KEY" -d '{"probe":"service","email":"probe@example.com","plan":"probe"}'
== no auth ==
401
== anon JWT ==
{"ok":true}
200
== service JWT ==
{"ok":true}
200
#5exit 0
psql "$SUPABASE_DB_URL" -c "select relname, relrowsecurity, relforcerowsecurity from pg_class where relname in ('signups','webhook_receipts');" -c "select policyname, cmd, roles from pg_policies where schemaname='public';"
     relname      | relrowsecurity | relforcerowsecurity 
------------------+----------------+---------------------
 signups          | f              | f
 webhook_receipts | f              | f
(2 rows)

 policyname | cmd | roles 
------------+-----+-------
(0 rows)

#6exit 0
cat > /tmp/setup_webhook.sql <<EOF
-- 1. Async HTTP from the database
create extension if not exists pg_net;

-- 2. Store the project JWT in the vault (never in plain function source)
do \$\$
begin
  if exists (select 1 from vault.secrets where name = 'hook_recorder_service_role_key') then
    update vault.secrets
       set secret = '${SUPABASE_SERVICE_ROLE_KEY}'
     where name = 'hook_recorder_service_role_key';
  else
    perform vault.create_secret('${SUPABASE_SERVICE_ROLE_KEY}',
                                'hook_recorder_service_role_key',
                                'JWT used by signups webhook trigger to call hook-recorder');
  end if;
end \$\$;

-- 3. Trigger function: fires per inserted row, queues an async POST via pg_net.
--    SECURITY DEFINER (owner postgres) so it works for inserts from ANY role/client.
create or replace function public.deliver_signup_webhook()
returns trigger
language plpgsql
security definer
set search_path = public
as \$\$
declare
  v_url text := '${SUPABASE_URL}/functions/v1/hook-recorder';
  v_jwt text;
begin
  select decrypted_secret into v_jwt
    from vault.decrypted_secrets
   where name = 'hook_recorder_service_role_key';

  perform net.http_post(
    url     := v_url,
    body    := jsonb_build_object(
                 'id',         new.id,
                 'email',      new.email,
                 'plan',       new.plan,
                 'created_at', new.created_at
               ),
    headers := jsonb_build_object(
                 'Content-Type',  'application/json',
                 'Authorization', 'Bearer ' || v_jwt
               ),
    timeout_milliseconds := 5000
  );
  return new;
end;
\$\$;

alter function public.deliver_signup_webhook() owner to postgres;
revoke all on function public.deliver_signup_webhook() from public, anon, authenticated, service_role;

-- 4. Attach trigger
drop trigger if exists signups_webhook_after_insert on public.signups;
create trigger signups_webhook_after_insert
after insert on public.signups
for each row execute function public.deliver_signup_webhook();
EOF
psql "$SUPABASE_DB_URL" -v ON_ERROR_STOP=1 -f /tmp/setup_webhook.sql
CREATE EXTENSION
DO
CREATE FUNCTION
ALTER FUNCTION
REVOKE
DROP TRIGGER
CREATE TRIGGER
psql:/tmp/setup_webhook.sql:56: NOTICE:  trigger "signups_webhook_after_insert" for relation "public.signups" does not exist, skipping
#7exit 0
EMAIL="db-trigger-test-$(date +%s)@example.com"
echo "Test email: $EMAIL"
echo "== Insert via REST API (service-role client) =="
curl -s -w "\nHTTP %{http_code}\n" -X POST "$SUPABASE_URL/rest/v1/signups" \
  -H "apikey: $SUPABASE_SERVICE_ROLE_KEY" \
  -H "Authorization: Bearer $SUPABASE_SERVICE_ROLE_KEY" \
  -H "Content-Type: application/json" \
  -H "Prefer: return=representation" \
  -d "{\"email\":\"$EMAIL\",\"plan\":\"enterprise\"}"
echo "$EMAIL" > /tmp/test_email.txt
echo "== Waiting for async delivery =="
for i in 1 2 3 4 5 6; do
  sleep 2
  ROW=$(psql "$SUPABASE_DB_URL" -t -A -c "select id, payload from public.webhook_receipts where payload->>'email' = '$EMAIL' order by id desc limit 1;")
  if [ -n "$ROW" ]; then echo "RECEIVED after ~$((i*2))s:"; echo "$ROW"; break; fi
  echo "  ...not yet (${i}x2s)"
done
echo "== pg_net response log =="
psql "$SUPABASE_DB_URL" -c "select id, status_code, content, error_msg, created from net._http_response order by id desc limit 3;"
Test email: db-trigger-test-1784904915@example.com
== Insert via REST API (service-role client) ==
[{"id":1,"email":"db-trigger-test-1784904915@example.com","plan":"enterprise","created_at":"2026-07-24T14:55:15.976053+00:00"}]
HTTP 201
== Waiting for async delivery ==
RECEIVED after ~2s:
4|{"id": 1, "plan": "enterprise", "email": "db-trigger-test-1784904915@example.com", "created_at": "2026-07-24T14:55:15.976053+00:00"}
== pg_net response log ==
 id | status_code |   content   | error_msg |            created            
----+-------------+-------------+-----------+-------------------------------
  1 |         200 | {"ok":true} |           | 2026-07-24 14:55:15.981722+00
(1 row)

#8exit 0
EMAIL="psql-client-test-$(date +%s)@example.com"
psql "$SUPABASE_DB_URL" -c "insert into public.signups (email, plan) values ('$EMAIL','pro') returning id, email, plan;"
for i in 1 2 3 4 5; do
  sleep 2
  ROW=$(psql "$SUPABASE_DB_URL" -t -A -c "select payload from public.webhook_receipts where payload->>'email' = '$EMAIL';")
  [ -n "$ROW" ] && { echo "RECEIVED (~$((i*2))s): $ROW"; break; }
done
# remove the two pre-implementation probe receipts, keep test evidence
psql "$SUPABASE_DB_URL" -c "delete from public.webhook_receipts where payload->>'probe' is not null;" -c "select id, received_at, payload->>'email' as email, payload->>'plan' as plan from public.webhook_receipts order by id;" -c "select tgname, tgrelid::regclass from pg_trigger where tgname='signups_webhook_after_insert';"
 id |                  email                  | plan 
----+-----------------------------------------+------
  2 | psql-client-test-1784904941@example.com | pro
(1 row)

INSERT 0 1
RECEIVED (~2s): {"id": 2, "plan": "pro", "email": "psql-client-test-1784904941@example.com", "created_at": "2026-07-24T14:55:42.132663+00:00"}
DELETE 2
 id |          received_at          |                  email                  |    plan    
----+-------------------------------+-----------------------------------------+------------
  4 | 2026-07-24 14:55:16.287706+00 | db-trigger-test-1784904915@example.com  | enterprise
  5 | 2026-07-24 14:55:42.302613+00 | psql-client-test-1784904941@example.com | pro
(2 rows)

            tgname            | tgrelid 
------------------------------+---------
 signups_webhook_after_insert | signups
(1 row)

What it said at the end

Done — the webhook delivery now lives entirely inside the database and is proven end-to-end. **Implementation (all server-side, no external workers/cron/client code):** 1. Enabled the `pg_net` extension (Supabase's async HTTP engine built into Postgres). 2. Stored the project's service-role JWT in **Supabase Vault** (`vault.secrets`, name `hook_recorder_service_role_key`) — never embedded in plain function source. 3. Created `public.deliver_signup_webhook()` — a `SECURITY DEFINER` function (owner `postgres`, `search_path` pinned) that reads the JWT from `vault.decrypted_secrets` and queues an async `net.http_post` to `{SUPABASE_URL}/functions/v1/hook-recorder` with `Content-Type: application/json` and `Authorization: Bearer <jwt>` headers. Body includes the new row's `id`, `email`, `plan`, `created_at`. Function revoked from `public/anon/authenticated/service_role` so only the trigger can execute it. 4. Attached trigger `signups_webhook_after_insert` — `AFTER INSERT ON public.signups FOR EACH ROW`. Because it's a row trigger, it fires for **any** client/role (RLS on `signups` doesn't bypass table triggers). **End-to-end proof (two different client paths, both delivered in ~2s):** - Insert via **REST API** (service-role client) → `public.webhook_receipts` row 4: `{"id":1,"plan":"enterprise","email":"db-trigger-test-…@example.com",…}`; pg_net logged `status_code 200 / {"ok":true}`. - Insert via **raw psql** → receipt row 5: `{"id":2,"plan":"pro","email":"psql-client-test-…@example.com",…}`. - Earlier unauthenticated probe to the receiver returned 401, confirming the JWT requirement is genuinely satisfied by the trigger's Authorization header. I also cleaned up the two pre-implementation probe receipts; `webhook_receipts` now contains only the two real test deliveries, and the trigger is installed and active.

3 earlier narration turn(s) are in the raw transcript.

How it was graded

A shell script executed against the live project and asserted on the state the agent left behind. No model judged another model.

exit 0 OK

Check it yourself

Raw transcript · Task definition and verifier · Every attempt