{"id":30331923,"url":"https://github.com/pierre-h/secure-convex","last_synced_at":"2026-06-20T08:31:15.155Z","repository":{"id":310083021,"uuid":"1038639631","full_name":"pierre-H/secure-convex","owner":"pierre-H","description":"A library to secure your Convex database with Valibot and Permix","archived":false,"fork":false,"pushed_at":"2025-08-15T17:28:40.000Z","size":26,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-08-15T17:31:19.395Z","etag":null,"topics":["convex","permix","security","valibot","validation"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pierre-H.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-08-15T15:10:53.000Z","updated_at":"2025-08-15T17:28:43.000Z","dependencies_parsed_at":"2025-08-15T17:31:24.895Z","dependency_job_id":"5c392d4f-b258-466c-a8e5-cf3a3d9b16c9","html_url":"https://github.com/pierre-H/secure-convex","commit_stats":null,"previous_names":["pierre-h/secure-convex"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/pierre-H/secure-convex","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pierre-H%2Fsecure-convex","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pierre-H%2Fsecure-convex/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pierre-H%2Fsecure-convex/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pierre-H%2Fsecure-convex/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pierre-H","download_url":"https://codeload.github.com/pierre-H/secure-convex/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pierre-H%2Fsecure-convex/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":270940719,"owners_count":24671687,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-18T02:00:08.743Z","response_time":89,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["convex","permix","security","valibot","validation"],"created_at":"2025-08-18T04:00:37.151Z","updated_at":"2026-06-20T08:31:15.125Z","avatar_url":"https://github.com/pierre-H.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# secure-convex\n\n**secure-convex** is a lightweight TypeScript library that supercharges your [Convex](https://convex.dev) backend with **strongly-typed runtime validation** powered by [Valibot](https://valibot.dev) and **granular permission control** via [Permix](https://github.com/davethan/permix).\n\nIt’s designed to make your Convex functions **safer, cleaner, and easier to maintain** by ensuring:\n\n- **End-to-end strong typing** – from input validation to database writes.\n- Every function input is validated against a strict Valibot schema before execution.\n- Your **database schema is derived directly from Valibot schemas**, keeping data types in sync automatically.\n- Every **write operation** is validated against the corresponding Valibot schema before hitting the database.\n- Access rules are centralized and enforced consistently.\n- Developer experience stays smooth with minimal boilerplate.\n\n## Key features\n\n- ✅ **Automatic input validation** for Convex queries \u0026 mutations.\n- 🗄 **DB schema generation** from Valibot schemas.\n- 🔒 **Permission middleware** with flexible, composable rules.\n- 🛡 **Schema-validated writes** for consistent, safe data.\n- 🧑‍💻 **Full TypeScript support** with strong, inferred types everywhere.\n- ⚡ **Zero extra config** – just wrap your functions.\n- 🧩 Works perfectly with existing Convex codebases.\n\n## Get started\n\nCreate you schema with valibot :\n\n```ts\n// convex/db.ts\nimport * as v from \"valibot\";\nimport { convexId } from \"secure-convex\";\n\nexport enum PostStatus {\n    DRAFT,\n    PUBLISHED,\n}\n\nexport const myDb = {\n    users: {\n        name: v.pipe(v.string(), v.trim(), v.minLength(3), v.maxLength(100)),\n        email: v.pipe(v.string(), v.email(), v.maxLength(150)),\n    },\n    posts: {\n        userId: convexId(\"users\"),\n        title: v.pipe(v.string(), v.maxLength(100)),\n        status: v.enum(PostStatus),\n        highlighted: v.boolean(),\n        publishedAt: v.optional(v.number()), // timestamp\n    },\n};\n```\n\nUse it in your Convex schema:\n\n```ts\n// convex/schema.ts\nimport { defineSchema } from \"convex/server\";\nimport { defineSecureTable } from \"secure-convex\";\nimport { myDb } from \"./db.ts\";\n\nconst schema = defineSchema({\n    users: defineSecureTable(myDb.users).index(\"byEmail\", [\"email\"]),\n    posts: defineSecureTable(myDb.posts).index(\"byStatusHighlited\", [\n        \"status\",\n        \"highlighted\",\n    ]),\n});\n\nexport default schema;\n```\n\nThen, create a custom secure mutation :\n\n```ts\n// convex/test.ts\nimport { secureMutation } from \"secure-convex\";\nimport { myDb } from \"./db.ts\";\n\nconst myMutation = secureMutation(myDb);\n```\n\nWith myMutation, ctx.db will always performs `valibot.parseAsync` for `insert` `patch` and `replace`.\nThere is alse a `ctx.insecureDb` which is the original convex db object.\n\n### Notes\n\n- Always use `exactOptional`, not `optional` or `undefinedable`, as convex doesn't support the value undefined\n- for union or variant table, use `defineSecureUnionTable` instead of `defineSecureTable`\n\n## Permix\n\nYou can also create a permix object from your schema :\n\n```ts\n// convex/permix.ts\nimport { createPermixFromDataModel } from \"secure-convex\";\nimport type { DataModel } from \"../_generated/dataModel\";\n\nexport const permix = createPermixFromDataModel\u003c\n    DataModel,\n    {\n        users: {\n            action: \"edit\" | \"delete\";\n            dataRequired: true;\n        };\n        posts: {\n            action: \"read\";\n        };\n    }\n\u003e();\n```\n\nThe dataType is automatically inserted from the Convex data model for Convex table name.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpierre-h%2Fsecure-convex","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpierre-h%2Fsecure-convex","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpierre-h%2Fsecure-convex/lists"}