{"id":41698214,"url":"https://github.com/grip-on-software/export-exchange","last_synced_at":"2026-01-24T20:55:06.465Z","repository":{"id":171609871,"uuid":"648151222","full_name":"grip-on-software/export-exchange","owner":"grip-on-software","description":"Tools for securely uploading files via HTTPS and GPG","archived":false,"fork":false,"pushed_at":"2024-07-23T14:12:20.000Z","size":79,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-09-05T03:24:53.703Z","etag":null,"topics":["gpg-encryption","secure-upload"],"latest_commit_sha":null,"homepage":"https://gros.liacs.nl","language":"Python","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/grip-on-software.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":"CITATION.cff","codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2023-06-01T10:18:03.000Z","updated_at":"2024-07-23T14:12:23.000Z","dependencies_parsed_at":null,"dependency_job_id":"235e688b-8e50-4366-9a22-584228e9dcae","html_url":"https://github.com/grip-on-software/export-exchange","commit_stats":null,"previous_names":["grip-on-software/export-exchange"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/grip-on-software/export-exchange","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/grip-on-software%2Fexport-exchange","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/grip-on-software%2Fexport-exchange/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/grip-on-software%2Fexport-exchange/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/grip-on-software%2Fexport-exchange/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/grip-on-software","download_url":"https://codeload.github.com/grip-on-software/export-exchange/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/grip-on-software%2Fexport-exchange/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28736791,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-24T19:23:36.361Z","status":"ssl_error","status_checked_at":"2026-01-24T19:23:28.966Z","response_time":89,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["gpg-encryption","secure-upload"],"created_at":"2026-01-24T20:55:05.787Z","updated_at":"2026-01-24T20:55:06.459Z","avatar_url":"https://github.com/grip-on-software.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Export exchange\n\n[![PyPI](https://img.shields.io/pypi/v/gros-export-exchange.svg)](https://pypi.python.org/pypi/gros-export-exchange)\n[![Build \nstatus](https://github.com/grip-on-software/export-exchange/actions/workflows/upload-tests.yml/badge.svg)](https://github.com/grip-on-software/export-exchange/actions/workflows/upload-tests.yml)\n[![Coverage \nStatus](https://coveralls.io/repos/github/grip-on-software/export-exchange/badge.svg?branch=master)](https://coveralls.io/github/grip-on-software/export-exchange?branch=master)\n[![Quality Gate\nStatus](https://sonarcloud.io/api/project_badges/measure?project=grip-on-software_export-exchange\u0026metric=alert_status)](https://sonarcloud.io/project/overview?id=grip-on-software_export-exchange)\n[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.12773659.svg)](https://doi.org/10.5281/zenodo.12773659)\n\nThis repository includes tools for securely uploading certain files (such as \ndatabase dumps) to a remote server via HTTPS and GPG encryption and \nauthenticated key exchanges. Although available as a package, it is mostly \nmeant to run as a standalone program.\n\n## Installation\n\nThe [GPG exchange](https://github.com/lhelwerd/gpg-exchange) library is \nrequired to be in a working state. Follow the instructions there to install the \nGPG dependencies first. Then, to install the latest release version of the \npackaged program from PyPI, run the following command:\n\n```\npip install gros-export-exchange\n```\n\nIn order to install `keyring` which is able to store authentication passwords \nand GPG passphrases, use `pip install gros-export-exchange[keyring]`.\n\nAnother option is to build the program from this repository, which allows using \nthe most recent development code. Run `make setup` to install the dependencies. \nThe uploader itself may then be installed with `make install`, which places the \npackage in your current environment. We recommend using a virtual environment \nduring development.\n\n## Configuration\n\nConfigure server settings in `settings.cfg` by copying `settings.cfg.example`\nor the example file below:\n```ini\n[upload]\nserver = $UPLOAD_SERVER\nverify = $UPLOAD_VERIFY\nauth = $UPLOAD_AUTH\nkeyring = $UPLOAD_KEYRING\nusername = $UPLOAD_USERNAME\npassword = $UPLOAD_PASSWORD\nengine = $UPLOAD_ENGINE\nhome_dir = $UPLOAD_HOME_DIR\nserver_key = $UPLOAD_SERVER_KEY\nname = $UPLOAD_NAME\nemail = $UPLOAD_EMAIL\npassphrase = $UPLOAD_PASSPHRASE\n```\nReplace the variables with actual values (or leave them out if they should be \nunset or retrieved from a different source). The settings file can also be \nchosen by prefixing the command in the [running](#running) section with \n`GATHERER_SETTINGS_FILE=path/to/settings.cfg`. Despite the environment variable \nname, there is no overlap between this configuration and the [data-gathering \nconfiguration](https://gros.liacs.nl/data-gathering/configuration.html).\n\nThe following configuration items are recognized in the `upload` section of the \nsettings file, but command-line arguments may override them:\n\n- `server`: URL (with the base path) to the upload server endpoint.\n- `verify`: Verification of the HTTPS certificate of the endpoint. This can be \n  `true` to enable verification against the installed certificates, `false` or \n  empty to disable verification, or a path to verify against a specific \n  certificate file available locally.\n- `auth`: Authentication class to use for the endpoint. This can be `basic` or \n  `digest`. The reference implementation of the upload endpoint uses `digest`.\n- `keyring`: Name of a keyring domain to use to retrieve the password for the \n  upload user to authenticate with. If left empty or the `keyring` dependency \n  is not installed, then the password must be provided via the `password` \n  setting or argument, which is less secure.\n- `username`: Username to authenticate with at the endpoint.\n- `password`: Password to authenticate with at the endpoint. If the `keyring` \n  is provided, then this is ignored.\n- `engine`: Path to the GPG engine binary. Example: `/usr/bin/gpg2`.\n- `home_dir`: Path to the configuration directory of the GPG engine. Example: \n  `/home/agent/.gnupg`, where `agent` is the current user (for example in the \n  Docker image).\n- `name`: Name to use to generate or find the keypair with. This should be \n  identifiable as to which source is uploading the exported files.\n- `email`: Email address to generate the keypair with. This should typically \n  refer to the person responsible for the exported files at the organization.\n- `passphrase`: Passphrase to use to protect the client's private key. This is \n  used to set the passphrase during generation and, if there is no `keyring`, \n  when data is encrypted or decrypted during the exchange. Preferably, the \n  passphrase argument is passed in only during generation and stored in the \n  keyring for future use.\n\nThe keyring backend should store two credentials if used:\n\n- Under the `username` provided as setting or argument, store the password used \n  for the digest authentication at the endpoint.\n- Under the \"privkey\" username, store the private key's passphrase.\n\n## Running\n\nInitiate the upload using the following command:\n\n```\ngros-export-exchange --files LIST OF ACCEPTABLE FILES\n```\n\nThe `Jenkinsfile` in this repository contains example steps for a Jenkins CI \ndeployment to regularly perform a database dump of a Grip on Software (GROS) \ndatabase via the database maintenance scripts in the \n[monetdb-import](https://github.com/grip-on-software/monetdb-import) repository \nand the database export application from \n[monetdb-dumper](https://github.com/grip-on-software/monetdb-dumper), also \nskipping unencrypted personal data. The files are then uploaded using the \nexport exchange tool to an endpoint running the [encrypted file upload \nserver](https://github.com/grip-on-software/upload).\n\n## Development and testing\n\nTo run tests, first install the test dependencies with `make setup_test` which \nalso installs all dependencies for the uploader. Then `make coverage` provides \ntest results in the output and in XML versions compatible with, e.g., JUnit and \nSonarQube available in the `test-reports/` directory. If you do not need XML \noutputs, then run `make test` to just report on test successes and failures or \n`make cover` to also have the terminal report on hits and misses in statements \nand branches.\n\n[GitHub Actions](https://github.com/grip-on-software/export-exchange/actions) \nis used to run the unit tests and report on coverage on commits and pull \nrequests. This includes quality gate scans tracked by \n[SonarCloud](https://sonarcloud.io/project/overview?id=grip-on-software_export-exchange) \nand [Coveralls](https://coveralls.io/github/grip-on-software/export-exchange) \nfor coverage history.\n\nThe Python module conforms to code style and typing standards which can be \nchecked using Pylint with `make pylint` and mypy with `make mypy`, after \ninstalling the pylint and mypy dependencies using `make setup_analysis`; typing \nreports are XML formats compatible with JUnit and SonarQube placed in the \n`mypy-report/` directory. To also receive the HTML report, use `make mypy_html` \ninstead.\n\nWe publish releases to [PyPI](https://pypi.org/project/gros-export-exchange/) \nusing `make setup_release` to install dependencies and `make release` which \nperforms multiple checks: unit tests, typing, lint and version number \nconsistency. The release files are also published on \n[GitHub](https://github.com/grip-on-software/export-exchange/releases) and from \nthere are archived on [Zenodo](https://zenodo.org/doi/10.5281/zenodo.12773658). \nNoteworthy changes to the module are added to the [changelog](CHANGELOG.md).\n\n## License\n\nGROS export exchange tools for securely uploading files via HTTPS and GPG are \nlicensed under the Apache 2.0 License.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgrip-on-software%2Fexport-exchange","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgrip-on-software%2Fexport-exchange","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgrip-on-software%2Fexport-exchange/lists"}