{"id":31658380,"url":"https://github.com/couchbase/gocbencryption","last_synced_at":"2025-10-07T15:20:59.980Z","repository":{"id":57513672,"uuid":"126255923","full_name":"couchbase/gocbencryption","owner":"couchbase","description":null,"archived":false,"fork":false,"pushed_at":"2021-10-07T16:25:41.000Z","size":77,"stargazers_count":1,"open_issues_count":3,"forks_count":2,"subscribers_count":31,"default_branch":"master","last_synced_at":"2025-08-15T07:43:40.691Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/couchbase.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}},"created_at":"2018-03-22T00:13:03.000Z","updated_at":"2021-10-07T16:25:46.000Z","dependencies_parsed_at":"2022-09-26T17:51:17.626Z","dependency_job_id":null,"html_url":"https://github.com/couchbase/gocbencryption","commit_stats":null,"previous_names":["couchbaselabs/gocbfieldcrypt"],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/couchbase/gocbencryption","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/couchbase%2Fgocbencryption","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/couchbase%2Fgocbencryption/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/couchbase%2Fgocbencryption/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/couchbase%2Fgocbencryption/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/couchbase","download_url":"https://codeload.github.com/couchbase/gocbencryption/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/couchbase%2Fgocbencryption/sbom","scorecard":{"id":305912,"data":{"date":"2025-08-11","repo":{"name":"github.com/couchbase/gocbencryption","commit":"08b40e1e7ecedd74a1f865338c795077a6b08202"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.9,"checks":[{"name":"Code-Review","score":7,"reason":"Found 12/16 approved changesets -- score normalized to 7","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":"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":"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":"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":"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":"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":"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":"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":"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":"License","score":9,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Warn: project license file does not contain an FSF or OSI license."],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"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-17T22:02:35.454Z","repository_id":57513672,"created_at":"2025-08-17T22:02:35.454Z","updated_at":"2025-08-17T22:02:35.454Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278796304,"owners_count":26047404,"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","status":"online","status_checked_at":"2025-10-07T02:00:06.786Z","response_time":59,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":[],"created_at":"2025-10-07T15:20:57.516Z","updated_at":"2025-10-07T15:20:59.974Z","avatar_url":"https://github.com/couchbase.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Couchbase Field Level Encryption for GO SDK\nField Level based Encryption library for the Go Couchbase SDK. Encrypted fields are protected in transit and at rest. The library provides functionality for encryption and decryption.\n\n## Getting Started ##\n```\ngo get github.com/couchbase/gocbencryption/v2\n```\n\nThe Couchbase Go Field Level Encryption (FLE) library uses struct tags to specify which field(s) to apply encryption to and what provider to use.\nThe struct tag key is `encrypted` and the value is of the form `\"encrypter-alias\"`. \nHere’s an example struct definition:\n\n```\ntype PersonAddress struct {\n\tHouseName  string `json:\"houseName\" encrypted:\"one\"`\n\tStreetName string `json:\"streetName\"`\n}\n\ntype Person struct {\n\tFirstName string        `json:\"firstName\"`\n\tLastName  string        `json:\"lastName\"`\n\tPassword  string        `json:\"password\" encrypted:\"one\"`\n\tAddress   PersonAddress `json:\"address\" encrypted:\"two\"`\n\n\tPhone string `json:\"phone\" encrypted:\"two\"`\n}\n```\nYou need to create a Key Store, a CryptoManager, (at least one) Provider and a Transcoder.\n\n* The provider provides encrypters and decrypters.\n* The transcoder is responsible for calling into the manager for each encrypted field during operations.\n* The manager is responsible for using providers to encrypt and decrypt fields.\n* You can register multiple (uniquely aliased) encryptors with a manager.\n* You can also register multiple decryptors with a manager, although only per algorithm.\n\nAfter installing the dependency you need to set up your Key Store, Manager, Provider and Transcoder (note that the key id passed to an encrypter matches the struct tags):\n\n```\n// Create our keys.\nkeyB := []byte{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,\n    0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,\n    0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,\n    0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x3f, 0x3f, 0x3f, 0x3f, 0x3d, 0x3e, 0x3f,\n}\nkey1 := gocbfieldcrypt.Key{\n    ID:    \"mykey\",\n    Bytes: keyB,\n}\nkey2 := gocbfieldcrypt.Key{\n    ID:    \"myotherkey\",\n    Bytes: keyB,\n}\n\n// Create the keyring and add both of these keys.\n// You should use a secure keyring in your application.\nkeyring := gocbfieldcrypt.NewInsecureKeyring()\nkeyring.Add(key)\nkeyring.Add(key2)\n\n\n// Create a provider.\n// AES-256 authenticated with HMAC SHA-512. Requires a 64-byte key.\nprovider := gocbfieldcrypt.NewAeadAes256CbcHmacSha512Provider(keyring)\n\n// Create the manager and add the providers.\nmgr := gocbfieldcrypt.NewDefaultCryptoManager(nil)\n\n// We need to create and then register encrypters.\n// The keyID here is used by the encrypter to lookup the key from the store when encrypting a document.\n// The key.ID returned from the store at encryption time is written into the data for the field to be encrypted.\n// The key ID that was written is then used on the decrypt side to find the corresponding key from the store.\nkeyOneEncrypter := provider.EncrypterForKey(key1.ID)\n\n// We register the providers for both encryption and decryption.\n// The alias used here is the value which corresponds to the \"encrypted\" field annotation.\nerr := mgr.RegisterEncrypter(\"one\", keyOneEncrypter)\nif err != nil {\n    panic(err)\n}\n\nerr = mgr.RegisterEncrypter(\"two\", provider.EncrypterForKey(key2.ID))\nif err != nil {\n    panic(err)\n}\n\n// We don't need to add a default encryptor but if we do then any fields with an\n// empty encrypted tag will use this encryptor.\nerr = mgr.DefaultEncrypter(keyOneEncrypter)\nif err != nil {\n    panic(err)\n}\n\n// We only set one decrypter per algorithm.\n// The crypto manager will work out which decrypter to use based on the alg field embedded in the field data.\n// The decrypter will use the key embedded in the field data to determine which key to fetch from the key store for decryption.\nerr = mgr.RegisterDecrypter(provider.Decrypter())\nif err != nil {\n    panic(err)\n}\n\n// Create our transcoder, not setting a base transcoder will cause it to fallback to the\n// SDK JSON transcoder.\ntranscoder := gocbfieldcrypt.NewTranscoder(nil, mgr)\n```\n\nNext you need to create a configuration to connect to your cluster and set your transcoder on the cluster options:\n\n```\ncluster, err := gocb.Connect(\"localhost\", gocb.ClusterOptions{\n    Username:   \"username\",\n    Password:   \"password\",\n    Transcoder: transcoder,\n})\nif err != nil {\n    panic(err)\n}\n\nb := cluster.Bucket(\"default\")\ncol := b.DefaultCollection()\n```\n\nYou can then perform KV operations and your data will be encrypted/decrypted automatically:\n```\nperson := Person{\n    FirstName: \"Barry\",\n    LastName:  \"Sheen\",\n    Password:  \"bang!\",\n    Address: PersonAddress{\n        HouseName:  \"my house\",\n        StreetName: \"my street\",\n    },\n    Phone: \"123456\",\n}\n\n_, err = col.Upsert(\"p1\", person, nil)\nif err != nil {\n    panic(err)\n}\n\nres, err := col.Get(\"p1\", nil)\nif err != nil {\n    panic(err)\n}\n\n// We can get the content like this in order to not decrypt any of the data.\n// If we didn't have the full set of keys then we could use this to manually decrypt specific fields.\nvar resData map[string]interface{}\nerr = res.Content(\u0026resData)\nif err != nil {\n    panic(err)\n}\n\nfmt.Printf(\"%+v\\n\", resData)\n\ngetData, err := col.Get(\"p1\", nil)\nif err != nil {\n    panic(err)\n}\n\n// If we fetch the data into a type which is annotated then the fields will automatically be decrypted using the registered\n// decrypters and keys.\nvar getPerson Person\nerr = res.Content(\u0026getPerson)\nif err != nil {\n    panic(err)\n}\n\nfmt.Printf(\"%+v\", person)\n```\n\n### Limitations\n\nDue to how the FLE library works `interface{}` fields are not currently supported.\nIf the `interface{}` field itself is being encrypted then the library will work, e.g.:\n\n```\ntype Person struct {\n    FirstName string        `json:\"firstName\"`\n    LastName  interface{}   `json:\"lastName\"`\n}\n```\n\nHowever, if the `interface{}` field is a complex object, or an array of objects, then any nested annotated fields will not be encrypted at the field level.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcouchbase%2Fgocbencryption","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcouchbase%2Fgocbencryption","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcouchbase%2Fgocbencryption/lists"}