{"id":38023240,"url":"https://github.com/maja42/ember","last_synced_at":"2026-01-16T19:31:44.954Z","repository":{"id":57540231,"uuid":"288151545","full_name":"maja42/ember","owner":"maja42","description":"Embed arbitrary resources into a go executable at runtime, after the executable has been built.","archived":false,"fork":false,"pushed_at":"2024-11-13T07:14:46.000Z","size":47,"stargazers_count":79,"open_issues_count":0,"forks_count":7,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-11-13T08:18:43.620Z","etag":null,"topics":["embed","embedding","go"],"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/maja42.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":"2020-08-17T10:33:58.000Z","updated_at":"2024-11-13T07:14:35.000Z","dependencies_parsed_at":"2024-03-26T11:29:36.093Z","dependency_job_id":"532af052-bbfe-45aa-8b47-c696f2c040f5","html_url":"https://github.com/maja42/ember","commit_stats":null,"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"purl":"pkg:github/maja42/ember","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/maja42%2Fember","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/maja42%2Fember/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/maja42%2Fember/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/maja42%2Fember/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/maja42","download_url":"https://codeload.github.com/maja42/ember/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/maja42%2Fember/sbom","scorecard":{"id":613111,"data":{"date":"2025-08-11","repo":{"name":"github.com/maja42/ember","commit":"9d7e97e00c783e4299b96c13b0ac6c6234a568c6"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3,"checks":[{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Code-Review","score":0,"reason":"Found 0/22 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"SAST","score":0,"reason":"no SAST tool detected","details":["Warn: no pull requests merged into dev branch"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-21T03:08:39.286Z","repository_id":57540231,"created_at":"2025-08-21T03:08:39.286Z","updated_at":"2025-08-21T03:08:39.286Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28481801,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-16T11:59:17.896Z","status":"ssl_error","status_checked_at":"2026-01-16T11:55:55.838Z","response_time":107,"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":["embed","embedding","go"],"created_at":"2026-01-16T19:31:44.871Z","updated_at":"2026-01-16T19:31:44.931Z","avatar_url":"https://github.com/maja42.png","language":"Go","readme":"# ember\r\n\r\n[![Go Report Card](https://goreportcard.com/badge/github.com/maja42/ember)](https://goreportcard.com/report/github.com/maja42/ember)\r\n[![GoDev](https://img.shields.io/badge/go.dev-reference-blue)](https://godoc.org/github.com/maja42/ember)\r\n\r\nEmber is a lightweight library and tool for embedding arbitrary resources into a go executable at runtime.\r\nThe resources don't need to exist at compile time.\r\n\r\nEmbedding binary files (eg. zip-archives and executables) is supported.\r\n\r\n## Use case\r\n\r\nApplications often require runtime- or user-defined configuration and resources to be stored alongside\r\nthe executable. \\\r\nThis forces the end-user to deal with multiple files when copying, moving or distributing the application. \r\nIt also allows end users to manipulate those attachments, which is not always desirable.\r\n\r\nThe main use-case of ember is to bundle such configuration files and other resources with the application at runtime.\r\nThere is no need for setting up a go toolchain to (re-)build the application every time there is a new configuration.\r\n\r\n## Cross platform\r\n\r\nEmber is truly cross-platform. It supports any OS, and embedding resources can also be done cross-platform. \\\r\nThis means that files can be attached to windows executables on both windows and linux and vice-versa.\r\n\r\n## Usage\r\n\r\nEmber consists of two parts. \r\n1. The `ember` package is imported by the application that receives attachments.\r\n2. The `ember/embedding` package is used by a separate application that attaches files to the already-compiled target executable. \\\r\nIt can also be used to remove previously attached data from an augmented executable. \\\r\nThe package can be used as a library. Alternatively there exists a CLI tool at `ember/cmd/embedder`.\r\n\r\n## Example\r\n\r\nThe following example can also be found at `examples/list`.\r\n\r\n### Access embedded files from within the target application\r\n\r\n```go\r\npackage main\r\n\r\nimport (\r\n\t\"fmt\"\r\n\t\"io\"\r\n\t\"log\"\r\n\t\"os\"\r\n\r\n\t\"github.com/maja42/ember\"\r\n)\r\n\r\nfunc main() {\r\n\tattachments, err := ember.Open()\r\n\tif err != nil {\r\n\t\tlog.Fatal(err)\r\n\t}\r\n\tdefer attachments.Close()\r\n\r\n\tfmt.Printf(\"Executable contains %d attachments\\n\", attachments.Count())\r\n\tcontents := attachments.List()\r\n\r\n\tfor _, name := range contents {\r\n\t\ts := attachments.Size(name)\r\n\t\tfmt.Printf(\"\\nAttachment %q has %d bytes:\\n\", name, s)\r\n\t\t\r\n\t\tr := attachments.Reader(name)\r\n\t\tio.Copy(os.Stdout, r)\r\n\t\tfmt.Println()\r\n\t}\r\n}\r\n```\r\n\r\n### Embed files into a target executable\r\n\r\nTo embed files into a compiled go executable you can use the CLI tool at `cmd/embedder`. \r\nAlternatively, you can also integrate embedding-logic into your own application by importing `ember/embedding` (see the [GoDoc](https://godoc.org/github.com/maja42/ember/embedding) for more information).\r\n\r\nTo use `cmd/embedder`, first create an `attachments.json` file describing the files to embed:\r\n\r\n```json\r\n{\r\n  \"file A\": \"path/to/file A.txt\",\r\n  \"file B\": \"path/to/file B.txt\"\r\n}\r\n```\r\n\r\nAfterwards, attach the files to an already-built executable:\r\n\r\n```bash\r\ncd cmd/embedder\r\ngo build\r\n./embedder -attachments ./attachments.json -exe ./myApp -out ./myFinishedApp\r\n```\r\n\r\n## How does it work?\r\n\r\nember uses a very primitive approach for embedding data to support any platform and to be independent of the go version, compiler, linker and so on.\r\n\r\nWhen embedding, the executable file is modified by simply appending additional data at the end.\r\nTo detect the boundary between the original executable and the attachments, a special marker-string (magic string) is inserted in-between.\r\n\r\n\r\n```\r\n   +---------------+\r\n   |               |\r\n   |    original   |\r\n   |   executable  |\r\n   |               |\r\n   +---------------+\r\n   | marker-string |\r\n   +---------------+\r\n   |      TOC      |\r\n   +---------------+\r\n   | marker-string |\r\n   +---------------+\r\n   |     file1     | \r\n   +---------------+\r\n   |     file2     |\r\n   +---------------+\r\n   |     file3     |\r\n   +---------------+\r\n```\r\n\r\nWhen starting the application and opening the attachments, the executable file is opened and searched for that specific marker string.\r\n\r\nThe first blob appended to the executable is a TOC (table of contents) that lists all files, their size and byte-offset.\r\nThis allows iterating and reading the individual attachments without seeking through the whole executable.\r\nIt also compares sizes and offsets to ensure that the executable is consistent and complete.\r\n\r\nAll content afterwards is the attached data.\r\n\r\nember also performs a variety of security-checks to ensure that the produced executable will work correctly:\r\n- Check if the application imported `maja42/ember` in a compatible version\r\n- Ensure that the executable does not already contain attachments\r\n\r\nThis approach also allows the use of exe-packers (compressors) and code signing.\r\n\r\n## Contributions\r\n\r\nFeel free to submit feature requests, bug reports and pull requests.\r\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmaja42%2Fember","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmaja42%2Fember","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmaja42%2Fember/lists"}