{"id":26675622,"url":"https://github.com/linkdata/rinse","last_synced_at":"2026-04-02T00:56:27.130Z","repository":{"id":255644687,"uuid":"849807601","full_name":"linkdata/rinse","owner":"linkdata","description":"Document cleaner","archived":false,"fork":false,"pushed_at":"2025-03-21T22:31:18.000Z","size":573,"stargazers_count":0,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-21T23:27:41.819Z","etag":null,"topics":["cleaner","document","golang","gvisor","podman"],"latest_commit_sha":null,"homepage":"","language":"Go","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/linkdata.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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}},"created_at":"2024-08-30T09:35:53.000Z","updated_at":"2025-03-21T22:31:01.000Z","dependencies_parsed_at":"2024-09-06T13:26:32.057Z","dependency_job_id":"1a00fd17-e8ef-4ed4-8bef-fcff8191099c","html_url":"https://github.com/linkdata/rinse","commit_stats":null,"previous_names":["linkdata/rinse"],"tags_count":106,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/linkdata%2Frinse","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/linkdata%2Frinse/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/linkdata%2Frinse/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/linkdata%2Frinse/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/linkdata","download_url":"https://codeload.github.com/linkdata/rinse/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245579675,"owners_count":20638679,"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":["cleaner","document","golang","gvisor","podman"],"created_at":"2025-03-26T03:18:55.944Z","updated_at":"2026-02-20T09:03:15.665Z","avatar_url":"https://github.com/linkdata.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# rinse\n\nWeb service that converts untrusted documents to image-based PDF:s in a sandbox.\n\nProvides both a Web UI and a Swagger REST API.\n\n![rinse-screenshot](https://github.com/user-attachments/assets/3ff19728-beb5-4354-a2f3-7ba9fdeee424)\n\n## Requirements\n\n* [podman](https://podman.io/) is required.\n\n## Running\n\nYou should start the container in [rootless](https://github.com/containers/podman/blob/main/docs/tutorials/rootless_tutorial.md) mode\nwith a read-only root filesystem. Inside the container we use [gVisor](https://gvisor.dev/) to further sandbox operations, and\nbecause gVisor requires the container to be started with `--cap-add=CAP_SYS_CHROOT`, we must add that argument. If you're using SELinux,\npodman will also need the `--security-opt label=type:container_engine_t` argument.\n\nIf you want the service to remember it's settings between runs, you'll need to mount a volume at `/etc/rinse` inside the container. More on this [here](#using-config-file).\n\n`podman run --read-only --cap-drop=ALL --cap-add=CAP_SYS_CHROOT --rm -d -p 8080:8080 -v $HOME:/etc/rinse ghcr.io/linkdata/rinse`\n\nRunning it with HTTPS requires you to provide valid certificates. Rinse will look for\n`fullchain.pem` and `privkey.pem` at `/etc/certs` inside the container, and if found\nstart in HTTPS mode.\n\n`podman run --read-only --cap-drop=ALL --cap-add=CAP_SYS_CHROOT --rm -d -p 8443:8443 -v $HOME:/etc/rinse -v $HOME/certs:/etc/certs ghcr.io/linkdata/rinse`\n\n### *Using config file*\nThe service will look for a config file named `rinse.json` in its data directory (datadir) to use when configuring its settings. The default path for datadir is `/etc/rinse` for regular users and `/var/rinse/` for root users, so the default config file path inside the container is `/etc/rinse/rinse.json`. If you wish to use a config file you need to either change the run script - either by adding another volume to mount or by create the mounted directory (`/tmp/rinse`) and placing the config within before running the script.\n\nIn this config file the following may be added:\n|Settings||||\n| -- | -- | -- | -- |\n| *What* | *Type* | *Default* | *Adjustable*\\* |\n| MaxSizeMB        |int| 2048 | yes |\n|\tCleanupSec      |int| 86400 | yes |\n|\tMaxTimeSec      |int| 86400 | yes |\n| TimeoutSec      |int| 600 | yes |\n|\tMaxConcurrent   |int| 2 | yes |\n|\tCleanupGotten   |bool| True | yes |\n|\tOAuth2          |JawsAuth.Config (nested)| - | - |\n|\tProxyURL        |string| - | yes |\n|\tAdmins          |[]string| - | yes |\n|\tEndpointForJWKs |string| - | - |\n\n\\* Can be changed during runtime by admins \n\nSee [JawsAuth](https://github.com/linkdata/jawsauth) or [jawsauth/config.go](https://github.com/linkdata/jawsauth/blob/main/config.go) specifically for details on JawsAuth.Config.\n\n## REST API\n\nThe container image will by default start `/usr/bin/rinse`, but it also provides a development version you can use by\noverriding the entrypoint with `--entrypoint /usr/bin/rinse-devel`. This version contains the full Swagger UI.\n\n## Process\n\nFirst, a temporary directory is created for the job. This will be mounted in the \ngVisor container as `/var/rinse`. If we were given an URL, we download the\ndocument and place it here.\n\nThen, each of these stages run in their own gVisor container, which is destroyed \nas soon as the stage is complete or fails. When the job is removed, all it's files\nare overwritten before they are deleted from the container filesystem.\n\n- We extract metadata about the document using [Apache Tika](https://tika.apache.org/)\n  and save it with the document file name plus `.json`.\n\nThe original document is renamed to `input` with it's extension preserved and made\nread-only before invoking the next stage.\n\n- If the language is to be auto-detected, [Apache Tika](https://tika.apache.org/)\n  is used to do so.\n\n- If the document is not a PDF, [LibreOffice](https://www.libreoffice.org/) is\n  used to try to covert it to one, and if successful, the original document\n  is deleted.\n\n- The `input.pdf` file is converted to a set of PNG files using\n  [`pdftoppm`](https://poppler.freedesktop.org/).\n\n- The set of PNG files is OCR-ed and processed into a PDF named\n  `output.pdf` using [`tesseract`](https://tesseract-ocr.github.io/).\n\n- Finally the `output.pdf` file is renamed to the original filename\n  (without extension) with `-rinsed.pdf` appended.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flinkdata%2Frinse","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flinkdata%2Frinse","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flinkdata%2Frinse/lists"}