Summary
Link mutations are unattributable: the created_by_api_key_id column exists in the schema but is never populated, so there is no audit trail of which API key created or overwrote a link.
Evidence
crates/vym-fyi-server-crud/migrations/20250101000000_init.sql:28 — created_by_api_key_id uuid REFERENCES api_keys(id) column exists.
crates/vym-fyi-model/src/services/repos.rs:72-106 (upsert) and repos.rs:194-229 (create_with_generated_slug) never write it; the handlers don't pass the creating key id (links.rs:255-300).
- The same-tenant upsert silently overwrites
target_url (repos.rs:82-85), so an authorized overwrite of a link leaves no trace of who did it or when.
Impact
Repudiation: no attribution for link creation or repointing. If a link is poisoned (see open-redirect issue) or a tenant's links are tampered with using a leaked key, there is no audit record to investigate or detect abuse.
Severity: MEDIUM.
Suggested fix
- Pass the authenticated key id (from
ApiKeyAuth) into the repository calls and populate created_by_api_key_id (and, if desired, an updated_at/updated_by_api_key_id trail).
- Note: this requires persisting key identity — currently API keys are config/env-driven and there is no key→id mapping; consider tracking the client_id at minimum.
Summary
Link mutations are unattributable: the
created_by_api_key_idcolumn exists in the schema but is never populated, so there is no audit trail of which API key created or overwrote a link.Evidence
crates/vym-fyi-server-crud/migrations/20250101000000_init.sql:28—created_by_api_key_id uuid REFERENCES api_keys(id)column exists.crates/vym-fyi-model/src/services/repos.rs:72-106(upsert) andrepos.rs:194-229(create_with_generated_slug) never write it; the handlers don't pass the creating key id (links.rs:255-300).target_url(repos.rs:82-85), so an authorized overwrite of a link leaves no trace of who did it or when.Impact
Repudiation: no attribution for link creation or repointing. If a link is poisoned (see open-redirect issue) or a tenant's links are tampered with using a leaked key, there is no audit record to investigate or detect abuse.
Severity: MEDIUM.
Suggested fix
ApiKeyAuth) into the repository calls and populatecreated_by_api_key_id(and, if desired, anupdated_at/updated_by_api_key_idtrail).