{"id":19564040,"url":"https://github.com/integrated-reasoning/keyhippo","last_synced_at":"2025-07-16T17:36:00.153Z","repository":{"id":253290786,"uuid":"839980895","full_name":"integrated-reasoning/KeyHippo","owner":"integrated-reasoning","description":"Issue API keys for your Supabase app with one line of SQL","archived":false,"fork":false,"pushed_at":"2025-01-29T23:00:13.000Z","size":1125,"stargazers_count":51,"open_issues_count":3,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-31T11:01:41.186Z","etag":null,"topics":["api","authentication","nix-flake","postgres","rls","supabase"],"latest_commit_sha":null,"homepage":"https://keyhippo.com","language":"PLpgSQL","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/integrated-reasoning.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-08-08T18:03:04.000Z","updated_at":"2025-03-12T20:30:24.000Z","dependencies_parsed_at":"2024-08-28T04:28:02.324Z","dependency_job_id":"b809170a-98fc-435b-9785-65d4feaaf6c6","html_url":"https://github.com/integrated-reasoning/KeyHippo","commit_stats":{"total_commits":325,"total_committers":2,"mean_commits":162.5,"dds":0.003076923076923088,"last_synced_commit":"84685f7cfe9332bb8f3a30c682d3db17838cadd5"},"previous_names":["integrated-reasoning/keyhippo"],"tags_count":36,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/integrated-reasoning%2FKeyHippo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/integrated-reasoning%2FKeyHippo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/integrated-reasoning%2FKeyHippo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/integrated-reasoning%2FKeyHippo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/integrated-reasoning","download_url":"https://codeload.github.com/integrated-reasoning/KeyHippo/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247657281,"owners_count":20974345,"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","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":["api","authentication","nix-flake","postgres","rls","supabase"],"created_at":"2024-11-11T05:19:49.941Z","updated_at":"2025-04-07T13:06:51.258Z","avatar_url":"https://github.com/integrated-reasoning.png","language":"PLpgSQL","funding_links":[],"categories":[],"sub_categories":[],"readme":"# KeyHippo\n\nKeyHippo extends Supabase's Row Level Security (RLS) to support API key authentication and Role-Based Access Control (RBAC) directly in Postgres.\n\n\u003c!-- markdownlint-disable-next-line --\u003e\n\u003cdiv align=\"center\"\u003e\n\n![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/integrated-reasoning/KeyHippo/test.yml)\n[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE-MIT)\n[![Super-Linter](https://github.com/integrated-reasoning/KeyHippo/actions/workflows/lint.yml/badge.svg)](https://github.com/marketplace/actions/super-linter)\n\n\u003c/div\u003e\n\n## Core Functionality\n\nKeyHippo enables API key authentication and fine-grained access control in Supabase applications while preserving Row Level Security policies. It handles both session-based and API key authentication using SQL and introduces an RBAC system for managing permissions.\n\nFeatures:\n\n- **API Key Management:**\n\n  - Secure key issuance and validation\n  - Key rotation and revocation\n  - Automatic key expiration\n  - Claims-based metadata\n  - HTTP notifications for key events\n\n- **Role-Based Access Control (RBAC):**\n  - Hierarchical group-based permissions\n  - Built-in roles (admin, user)\n  - Fine-grained permission management\n  - Default role assignment for new users\n\n## Quick Start\n\n### Database Setup\n\n1. Create a new Supabase migration for the KeyHippo extension:\n\n```bash\nsupabase migration new add_keyhippo_extension\n```\n\n2. Copy the contents of `extension/keyhippo--1.2.5.sql` into the newly created migration file in the `supabase/migrations` directory.\n\n3. Apply the migration to install the extension:\n\n```bash\nsupabase migration up\n```\n\n4. For projects with existing users:\n\n```sql\nSELECT keyhippo.initialize_existing_project();\n```\n\nThis will:\n\n- Create default groups (Admin Group, User Group)\n- Create default roles (Admin, User)\n- Set up default permissions\n- Create a default scope\n- Assign the User role to existing users (when using initialize_existing_project)\n\n## Application Integration\n\nKeyHippo integrates with your Supabase application in two main ways:\n\n1. **Direct SQL Access**: Use KeyHippo functions through your application's database connection\n2. **REST API**: Access via PostgREST endpoints (requires valid API key in x-api-key header)\n\n### Key Management\n\n```sql\n-- Generate a new API key\nSELECT * FROM keyhippo.create_api_key('Primary API Key', 'default');\n\n-- Verify an API key (internal use)\nSELECT * FROM keyhippo.verify_api_key('your-api-key');\n\n-- Get key metadata in RLS policies\nSELECT keyhippo.key_data();\n\n-- Revoke an API key\nSELECT keyhippo.revoke_api_key('key-id-uuid');\n\n-- Rotate an existing key\nSELECT * FROM keyhippo.rotate_api_key('key-id-uuid');\n\n-- Update key claims\nSELECT keyhippo.update_key_claims('key-id-uuid', '{\"custom\": \"data\"}'::jsonb);\n```\n\n### HTTP Integration\n\nKeyHippo supports HTTP notifications for:\n\n- Key expiry events\n- Audit log events\n- Installation tracking\n\nConfigure endpoints through keyhippo_internal.config:\n\n```sql\n-- Set audit log endpoint\nUPDATE keyhippo_internal.config\nSET value = 'https://your-endpoint.com/audit'\nWHERE key = 'audit_log_endpoint';\n\n-- Enable HTTP logging\nSELECT keyhippo_internal.enable_audit_log_notify();\n```\n\n### RLS Policy Implementation\n\nExample of a policy supporting both authentication methods and RBAC:\n\n```sql\nCREATE POLICY \"owner_access\"\nON \"public\".\"resource_table\"\nFOR SELECT\nUSING (\n  auth.uid() = resource_table.owner_id\n  AND keyhippo.authorize('manage_resources')\n);\n```\n\nThis policy grants access when:\n\n1. The user is authenticated (via session token or API key)\n2. They are the owner of the resource\n3. They have the 'manage_resources' permission\n\n### RBAC Management\n\nCreate a new group, role, and assign permissions:\n\n```sql\n-- Create a new group\nSELECT keyhippo_rbac.create_group('Developers', 'Group for developer users') AS group_id;\n\n-- Create a new role (role_type can be 'admin' or 'user')\nSELECT keyhippo_rbac.create_role('Developer', 'Developer role', group_id, 'user'::keyhippo.app_role) AS role_id;\n\n-- Assign permissions to the role (using valid app_permission enum values)\nSELECT keyhippo_rbac.assign_permission_to_role(role_id, 'manage_api_keys'::keyhippo.app_permission);\n\n-- Assign the role to a user\nSELECT keyhippo_rbac.assign_role_to_user(auth.uid(), group_id, role_id);\n```\n\nAvailable permissions:\n\n- manage_groups\n- manage_roles\n- manage_permissions\n- manage_scopes\n- manage_user_attributes\n- manage_api_keys\n\n### Impersonation Functionality\n\nKeyHippo provides secure user impersonation for debugging purposes:\n\n```sql\n-- Login as another user (requires postgres role)\nCALL keyhippo_impersonation.login_as_user('\u003cuser_id\u003e');\n\n-- Login as anonymous user (requires postgres role)\nCALL keyhippo_impersonation.login_as_anon();\n\n-- Perform actions as the impersonated user\n-- The session will automatically expire after 1 hour\n\n-- End impersonation session\nCALL keyhippo_impersonation.logout();\n```\n\n**Features:**\n\n- Requires postgres role for impersonation\n- Automatic session expiration (1 hour)\n- Audit logging of impersonation events\n- Support for anonymous user impersonation\n\n## Architecture\n\n### Database Schema\n\nKeyHippo organizes its functionality across several schemas:\n\n- **keyhippo**: Main schema for API key management and core functions\n- **keyhippo_rbac**: Role-Based Access Control functionality\n- **keyhippo_internal**: Internal configuration and utilities\n- **keyhippo_impersonation**: User impersonation functionality\n\n### API Key Management\n\nKeyHippo provides API key management with the following features:\n\n**Key Operations:**\n\n```sql\n-- Create a new API key\nSELECT * FROM keyhippo.create_api_key('My API Key', 'default');\n\n-- Revoke an existing key\nSELECT keyhippo.revoke_api_key('key-id-uuid');\n\n-- Rotate an existing key\nSELECT * FROM keyhippo.rotate_api_key('key-id-uuid');\n\n-- Update key claims\nSELECT keyhippo.update_key_claims('key-id-uuid', '{\"custom\": \"data\"}'::jsonb);\n```\n\n**Integration:**\n\n```sql\n-- Get current key data in RLS policies\nSELECT keyhippo.key_data();\n\n-- Check authorization in RLS policies\nSELECT keyhippo.authorize('manage_api_keys');\n\n-- Get current user context\nSELECT * FROM keyhippo.current_user_context();\n```\n\n## Role-Based Access Control (RBAC)\n\nKeyHippo provides a RBAC system that integrates with Postgres RLS policies:\n\n### RBAC Components\n\n- **Groups:** Logical grouping of users (e.g., \"Admin Group\", \"User Group\")\n- **Roles:** Assigned to users within groups, with role types:\n  - 'admin': Full system access\n  - 'user': Limited access based on assigned permissions\n- **Permissions:** Built-in permissions:\n  - manage_groups\n  - manage_roles\n  - manage_permissions\n  - manage_scopes\n  - manage_user_attributes\n  - manage_api_keys\n\n### Default Setup\n\nOn initialization, KeyHippo creates:\n\n1. Default groups: \"Admin Group\" and \"User Group\"\n2. Default roles: \"Admin\" (admin type) and \"User\" (user type)\n3. Admin role gets all permissions\n4. User role gets 'manage_api_keys' permission\n5. New users automatically get the \"User\" role\n\n### Usage Example\n\n```sql\n-- Check if user has permission in RLS policy\nSELECT keyhippo.authorize('manage_api_keys');\n\n-- Get current user's permissions\nSELECT permissions FROM keyhippo.current_user_context();\n```\n\n## Impersonation\n\nKeyHippo provides user impersonation functionality to assist with debugging and maintnence tasks.\n\n### Usage\n\n```sql\n-- Start impersonation (requires postgres role)\nCALL keyhippo_impersonation.login_as_user('\u003cuser_id\u003e');\n\n-- Impersonate anonymous user\nCALL keyhippo_impersonation.login_as_anon();\n\n-- End impersonation session\nCALL keyhippo_impersonation.logout();\n```\n\n### Security Controls\n\n- Only postgres role can initiate impersonation\n- Sessions automatically expire after 1 hour\n- All actions during impersonation are logged\n- Original role is preserved and restored on logout\n- State tracking prevents session manipulation\n\n### Integration with RLS\n\nKeyHippo's authentication and authorization integrate with Supabase's Row Level Security policies. Use auth.uid() to get the current user's ID and keyhippo.authorize() to check permissions within your RLS policies.\n\n**Example RLS Policy:**\n\n```sql\nCREATE POLICY \"user_can_view_own_data\" ON \"public\".\"user_data\"\n  FOR SELECT USING (\n    auth.uid() = user_data.user_id\n    AND keyhippo.authorize('manage_api_keys')\n  );\n```\n\nNote: The example uses 'manage_api_keys' as it's one of the built-in permissions. Your application can define additional permissions as needed.\n\n## Star History\n\n[![Star History Chart](https://api.star-history.com/svg?repos=integrated-reasoning/KeyHippo\u0026type=Timeline)](https://star-history.com/#integrated-reasoning/KeyHippo\u0026Timeline)\n\n## Contribution\n\nWe welcome community contributions. For guidance, see our Contributing Guide.\n\n## Licensing\n\nKeyHippo is distributed under the MIT license. See the LICENSE file for details.\n\n## Development\n\n### Setting Up Development Environment\n\n1. Install Nix (if not already installed):\n\nFor Linux/macOS (multi-user installation recommended):\n\n```bash\nsh \u003c(curl -L https://nixos.org/nix/install) --daemon\n```\n\nFor single-user installation:\n\n```bash\nsh \u003c(curl -L https://nixos.org/nix/install) --no-daemon\n```\n\n2. Clone the repository:\n\n```bash\ngit clone https://github.com/integrated-reasoning/KeyHippo.git\ncd KeyHippo\n```\n\n3. Enter the Nix development shell:\n\n```bash\nnix develop\n```\n\n4. Set up the local Supabase instance:\n\n```bash\nmake setup-supabase\n```\n\n### Running Tests\n\nKeyHippo uses pgTAP for testing. To run the test suite:\n\n```bash\n# Run all tests\nmake test\n\n# Run pgTAP tests specifically\nmake pg_tap\n```\n\nThe test suite verifies:\n\n- API key management functionality\n- RBAC system operations\n- Impersonation features\n- Security controls\n- Integration with RLS policies\n\n## Support \u0026 Community\n\nFor technical support and discussions:\n\n- Open an issue on our [GitHub repository](https://github.com/integrated-reasoning/KeyHippo/issues)\n- Follow us on [Twitter](https://x.com/keyhippo) for updates\n- Visit [keyhippo.com](https://keyhippo.com)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fintegrated-reasoning%2Fkeyhippo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fintegrated-reasoning%2Fkeyhippo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fintegrated-reasoning%2Fkeyhippo/lists"}