{"id":13471530,"url":"https://github.com/nhost/hasura-storage","last_synced_at":"2025-04-12T15:34:59.275Z","repository":{"id":37099919,"uuid":"409767133","full_name":"nhost/hasura-storage","owner":"nhost","description":"Storage for Hasura built on top of S3","archived":false,"fork":false,"pushed_at":"2025-03-11T09:34:35.000Z","size":29999,"stargazers_count":222,"open_issues_count":4,"forks_count":46,"subscribers_count":6,"default_branch":"main","last_synced_at":"2025-04-03T15:11:17.621Z","etag":null,"topics":["files","hasura","nhost","s3","storage","upload"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nhost.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","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":"2021-09-23T23:03:37.000Z","updated_at":"2025-03-26T07:45:49.000Z","dependencies_parsed_at":"2023-02-09T15:16:23.375Z","dependency_job_id":"702f75b1-59ce-403b-adbc-cb23319e4edf","html_url":"https://github.com/nhost/hasura-storage","commit_stats":null,"previous_names":[],"tags_count":35,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nhost%2Fhasura-storage","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nhost%2Fhasura-storage/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nhost%2Fhasura-storage/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nhost%2Fhasura-storage/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nhost","download_url":"https://codeload.github.com/nhost/hasura-storage/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248590067,"owners_count":21129742,"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":["files","hasura","nhost","s3","storage","upload"],"created_at":"2024-07-31T16:00:46.301Z","updated_at":"2025-04-12T15:34:59.234Z","avatar_url":"https://github.com/nhost.png","language":"Go","funding_links":[],"categories":["Go","Tools and Extensions"],"sub_categories":[],"readme":"# Hasura Storage\n\nHasura storage is a service that adds a storage service on top of hasura and any s3-compatible storage service. The goal is to be able to leverage the cloud storage service while also leveraging hasura features like its graphql API, permissions, actions, presets, etc...\n\n## Workflows\n\nTo understand what hasura-storage does we can look at the two main workflows to upload and retrieve files.\n\n### Uploading files\n\nWhen a user wants to upload a file hasura-storage will first check with hasura if the user is allowed to do so, if it the file will be uploaded to s3 and, on completion, file metadata will be stored in hasura.\n\n``` mermaid\nsequenceDiagram\n    actor User\n    autonumber\n    User-\u003e\u003e+hasura-storage: upload file\n    hasura-storage-\u003e\u003e+hasura: check permissions\n    hasura-\u003e\u003e-hasura-storage: return if user can upload file\n    hasura-storage-\u003e\u003e+s3: upload file\n    s3-\u003e\u003e-hasura-storage: file information\n    hasura-storage-\u003e\u003e+hasura: file metadata\n    hasura-\u003e\u003e-hasura-storage: success\n    hasura-storage-\u003e\u003e-User: file metadata\n```\n\n### Retrieving files\n\nSimilarly, when retrieving files, hasura-storage will first check with hasura if the user has permissions to retrieve the file and if the user is allowed, it will forward the file to the user:\n\n``` mermaid\nsequenceDiagram\n    actor User\n    autonumber\n    User-\u003e\u003e+hasura-storage: request file\n    hasura-storage-\u003e\u003e+hasura: check permissions\n    hasura-\u003e\u003e-hasura-storage: return if user can access file\n    hasura-storage-\u003e\u003e+s3: request file\n    s3-\u003e\u003e-hasura-storage: file\n    hasura-storage-\u003e\u003e-User: file\n```\n\n## Features\n\nThe main features of the service are:\n\n- leverage hasura's permissions to allow users to upload/retrieve files\n- upload files to any s3-compatible service\n- download files from any s3-compatible service\n- create presigned URLs to grant temporary access\n- caching information to integrate with caches and CDNs (cache headers, etag, conditional headers, etc)\n- perform basic image manipulation on the fly\n- integration with [clamav](https://www.clamav.net) antivirus\n\n## Antivirus\n\nIntegration with [clamav](https://www.clamav.net) antivirus relies on an external [clamd](https://docs.clamav.net/manual/Usage/Scanning.html#clamd) service. When a file is uploaded `hasura-storage` will create the file metadata first and then check if the file is clean with `clamd` via its TCP socket. If the file is clean the rest of the process will continue as usual. If a virus is found details about the virus will be added to the `virus` table and the rest of the process will be aborted.\n\n``` mermaid\nsequenceDiagram\n    actor User\n    User -\u003e\u003e storage: upload file\n    storage -\u003e\u003eclamav: check for virus\n    alt virus found\n        storage--\u003es3: abort upload\n        storage-\u003e\u003egraphql: insert row in virus table\n    else virus not found\n        storage-\u003e\u003es3: upload\n        storage-\u003e\u003egraphql: update metadata\n    end\n\n```\n\nThis feature can be enabled with the flag `--clamav-server string`, where `string` is the tcp address for the clamd service.\n\n## OpenAPI\n\nThe service comes with an [OpenAPI definition](/controller/openapi.yaml) which you can also see [online](https://editor.swagger.io/?url=https://raw.githubusercontent.com/nhost/hasura-storage/main/controller/openapi.yaml).\n\n## Using the service\n\nEasiest way to get started is by using [nhost](https://nhost.io)'s free tier but if you want to self-host you can easily do it yourself as well.\n\n### Self-hosting the service\n\nRequirements:\n\n1. [hasura](https://hasura.io) running, which in turns needs [postgres or any other supported database](https://hasura.io/docs/latest/graphql/core/databases/index/#supported-databases).\n2. An s3-compatible service. For instance, [AWS S3](https://aws.amazon.com/s3/), [minio](https://min.io), etc...\n\nA fully working example using docker-compose can be found [here](/build/dev/docker/). Just remember to replace the image `hasura-storage:dev` with a valid [docker image](https://hub.docker.com/r/nhost/hasura-storage/tags), for instance, `nhost/hasura-storage:0.1.5`.\n\n## Contributing\n\nIf you need help or want to contribute it is recommended to read the [contributing](/CONTRIBUTING.md) information first. In addition, if you plan to contribute with code it is also encouraged to read the [development](/DEVELOPMENT.md) guide.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnhost%2Fhasura-storage","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnhost%2Fhasura-storage","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnhost%2Fhasura-storage/lists"}