{"id":15625726,"url":"https://github.com/daniel15/securesign","last_synced_at":"2025-04-28T15:53:27.070Z","repository":{"id":139345663,"uuid":"107911775","full_name":"Daniel15/SecureSign","owner":"Daniel15","description":"Simple, secure Authenticode and GPG code signing server","archived":false,"fork":false,"pushed_at":"2022-12-09T08:45:51.000Z","size":80,"stargazers_count":23,"open_issues_count":6,"forks_count":9,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-04-28T15:53:20.331Z","etag":null,"topics":["authenticode","code-signing","gpg","gpgme","signcode","signing-server"],"latest_commit_sha":null,"homepage":"","language":"C#","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/Daniel15.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":"2017-10-22T23:47:22.000Z","updated_at":"2024-09-06T00:14:24.000Z","dependencies_parsed_at":null,"dependency_job_id":"5e9c2d91-dfb1-42eb-965c-66e9142991b5","html_url":"https://github.com/Daniel15/SecureSign","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Daniel15%2FSecureSign","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Daniel15%2FSecureSign/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Daniel15%2FSecureSign/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Daniel15%2FSecureSign/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Daniel15","download_url":"https://codeload.github.com/Daniel15/SecureSign/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251342718,"owners_count":21574243,"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":["authenticode","code-signing","gpg","gpgme","signcode","signing-server"],"created_at":"2024-10-03T10:02:20.954Z","updated_at":"2025-04-28T15:53:27.050Z","avatar_url":"https://github.com/Daniel15.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"SecureSign\n==========\n\nSecureSign is a simple code signing server. It is designed to allow Authenticode and GPG signing of build artifacts in a secure way, without exposing the private key.\n\nFeatures\n========\n - **Isolation**: Each unique call site has its own access token for the service. An access token only provides access to a single signing key, and can be restricted to only sign particular content.\n - **Encryption**: Private keys are encrypted at rest, using an encryption key that is not stored on the server. The encryption key is encoded into the access token, so the private key can not be decrypted without the access token.\n - **Cross-platform**: Supported on Windows and Linux, may run on other operating systems too.\n\nPrerequisites\n=============\n - [ASP.NET Core 2.0 runtime](https://www.microsoft.com/net/download/core#/runtime) must be installed\n - For Authenticode:\n   - On Linux, [osslsigncode](https://sourceforge.net/projects/osslsigncode/) needs to be installed. On Debian-based distros, you can `apt-get install osslsigncode`.\n   - On Windows, [signtool](https://docs.microsoft.com/en-us/dotnet/framework/tools/signtool-exe) needs to be installed. This comes with the Windows SDK.\n - For GPG:\n   - On Linux, `libgpgme.so.11` needs to be available. On Debian and Ubuntu, install the [libgpgme11](https://packages.debian.org/stretch/libgpgme11) package.\n   - On Windows, you will need to install [Gpg4Win](https://www.gpg4win.org/).\n\nUsage\n=====\nThe `publish.sh` script will build SecureSign into the `published` directory.\n\nBefore using SecureSign, you need to add your private signing keys. For Authenticode, ensure you have the key as a `.pfx` file. For GPG, ensure you export the secret key without a passphrase, and name the file with a `.gpg` extension.\n\nOnce you have your key file, use the `addkey` command:\n\n```\n$ dotnet SecureSign.Tools.dll addkey /tmp/my_key.pfx\nPassword? **********\n\nSaved my_key.pfx (Test code signing)\nSubject: CN=Test Code Signing\nIssuer: CN=Test Code Signing\nValid from 2016-11-20 1:51:47 PM until 2017-12-31 4:00:00 PM\n\nSecret Code: 2eiONi53ihUkxxewk5VliJO29hLM3S68LHkTkt9aKuX4dgRop99zw\n```\n\nThis secret code is the decryption key required to create access tokens that use this key. It is not saved anywhere, so if you lose it you will need to reinstall the key. For GPG, you will see **multiple** secret codes - One for each subkey.\n\nOnce the key has been added, create an access token for it using the `addtoken` command:\n```\n$ dotnet SecureSign.Tools.dll addtoken\nKey name? my_key.pfx\nSecret code? 2eiONi53ihUkxxewk5VliJO29hLM3S68LHkTkt9aKuX4dgRop99zw\nComment (optional)? Hello World\n\nSigning settings:\nDescription? Some App\nProduct/Application URL? https://dan.cx/SecureSignSample/\n\nCreated new access token:\nzGZEtxVisE2rqSf71SVqNg-CfDJ8BqN7wE-jn1Hj20Xn2jQTrtxA6zDlrQn0C3Ut....\n```\n\nSome of the access token information is saved into `accessTokenConfig.json`. Removing the access token from this config file will revoke its access.\n\nNow that an access token has been created, you can start the server:\n```\n$ dotnet SecureSign.Web.dll\nHosting environment: Production\nContent root path: /var/www/securesign\nNow listening on: http://[::]:5000\nApplication started. Press Ctrl+C to shut down.\n```\n\nTo Authenticode sign a file, send a POST request to `/sign/authenticode`. This can contain a URL to the artifact to sign:\n```\ncurl --show-error --fail \\\n  -X POST \\\n  -F 'accessToken=zGZEtxVis...' \\\n  -F 'artifactUrl=https://build.example.com/latest.msi' \\\n  -o latest-signed.msi \\\n  http://localhost:5000/sign/authenticode\n```\n\nAlternatively, it could contain the actual artifact itself:\n```\ncurl --show-error --fail \\\n  -X POST \\\n  -F 'accessToken=zGZEtxVis...' \\\n  -F 'artifact=@latest.msi' \\\n  -o latest-signed.msi \\\n  http://localhost:5000/sign/authenticode\n```\n\nSimilarly, for GPG, send a POST request to `/sign/gpg` instead.\n\nHTTPS\n-----\nTo use TLS, first obtain a certificate in .pfx format. Then, modify `appsettings.json` to specify the path to the certificate:\n```\n{\n  \"Kestrel\": {\n    \"EndPoints\": {\n      \"Https\": {\n        \"Url\": \"https://localhost:5001\",\n        \"Certificate\": {\n          \"Path\": \"\u003cpath to .pfx file\u003e\",\n          \"Password\": \"\u003ccertificate password\u003e\"\n        }\n      }\n    },\n    \"Logging\": {\n      \"LogLevel\": {\n        \"Default\": \"Information\",\n        \"Microsoft\": \"Warning\"\n      }\n    }\n  }\n}\n```\n\nRestricting Usage of Access Tokens\n----------------------------------\n\nBy default, an access token can be used to sign **any** file, either via upload or from **any** URL. To lock this down, you can modify `accessTokenConfig.json`. For example, to only allow `msi` files from `nightly.yarnpkg.com` to be signed, you can set `AllowUploads` to `false` and add the whitelist to `AllowedUrls`:\n```\n{\n  \"AccessTokens\": {\n    \"zGZEtxVisE2rqSf71SVqNg\": {\n      \"AllowUploads\": false,\n      \"AllowedUrls\": [\n      {\n        \"Domain\": \"^nightly.yarnpkg.com$\",\n        \"Path\": \"^/(.+)\\.msi$\"\n      }\n    ]\n  }\n}\n```\n\nEach item in the `AllowedUrls` array contains regular expressions to check the `Domain` and `Path` of the URL. The request will be allowed if any of the allowed URL patterns match.\n\nLocation of Encryption Keys and Certificates\n--------------------------------------------\n\nBy default, SecureSign's encryption keys are stored in a `keys` directory, and certificates are stored in a `secrets` directory. You can change these directories (for example, to use a directory that's encrypted at rest) by setting the `Paths` settings in `appconfig.json`:\n\n```json\n{\n  \"Paths\": {\n    \"EncryptionKeys\": \"/var/local/private/securesign-keys/\",\n    \"Certificates\": \"/var/local/private/securesign-certs/\"\n  }\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdaniel15%2Fsecuresign","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdaniel15%2Fsecuresign","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdaniel15%2Fsecuresign/lists"}