{"id":18369140,"url":"https://github.com/angusgmorrison/logfusc","last_synced_at":"2025-04-06T17:31:58.186Z","repository":{"id":164858172,"uuid":"640281606","full_name":"AngusGMorrison/logfusc","owner":"AngusGMorrison","description":"logfusc is a Go library that makes redacting sensitive data from logs and traces simple. Never log a secret again.","archived":false,"fork":false,"pushed_at":"2023-10-21T10:22:19.000Z","size":500,"stargazers_count":7,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-03-22T04:03:18.203Z","etag":null,"topics":[],"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/AngusGMorrison.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":"2023-05-13T15:14:45.000Z","updated_at":"2025-01-06T02:35:41.000Z","dependencies_parsed_at":null,"dependency_job_id":"fc0c7701-b74e-45e3-9b18-3efdaf0b37ec","html_url":"https://github.com/AngusGMorrison/logfusc","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AngusGMorrison%2Flogfusc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AngusGMorrison%2Flogfusc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AngusGMorrison%2Flogfusc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AngusGMorrison%2Flogfusc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/AngusGMorrison","download_url":"https://codeload.github.com/AngusGMorrison/logfusc/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247522447,"owners_count":20952553,"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":[],"created_at":"2024-11-05T23:28:34.951Z","updated_at":"2025-04-06T17:31:56.894Z","avatar_url":"https://github.com/AngusGMorrison.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# logfusc – surefire secret redaction for logs and traces\n\n[![Go\nReference](https://pkg.go.dev/badge/github.com/angusgmorrison/logfusc.svg)](https://pkg.go.dev/github.com/angusgmorrison/logfusc) ![CI](https://github.com/AngusGMorrison/logfusc/actions/workflows/vet.yml/badge.svg)\n\nInstrument your codebase with confidence. logfusc is a Go library that makes\nredacting sensitive data from logs and traces simple. Stop scrubbing logs in the\naftermath of preventable human errors. Make your secrets **unloggable**.\n\n![A family of gophers riding a log down a river](images/logging-gophers.jpg)\n\n\n## logfusc.Secret\n\n`logfusc.Secret` is a generic wrapper for any type that you want to redact from\nlogs, traces and other outputs.\n\n`Secret` implements `fmt.Stringer` and `fmt.GoStringer`, so no matter how hard\nyou try to format it, it doesn't give up its secret.\n\n```go\npassword := \"do not log!\"\nsecret := logfusc.NewSecret(password)\n\nfmt.Printf(\"%s\\n\", secret)\n// =\u003e logfusc.Secret[string]{REDACTED}\n\nfmt.Printf(\"%q\\n\", secret)\n// =\u003e \"logfusc.Secret[string]{REDACTED}\"\n\nfmt.Printf(\"%v\\n\", secret)\n// =\u003e \"logfusc.Secret[string]{REDACTED}\"\n\nfmt.Printf(\"%+v\\n\", secret)\n// =\u003e \"logfusc.Secret[string]{REDACTED}\"\n\nfmt.Printf(\"%#v\\n\", secret)\n// =\u003e \"logfusc.Secret[string]{REDACTED}\"\n\nfmt.Printf(\"%x\\n\", secret)\n// =\u003e 6c6f67667573632e5365637265745b737472696e675d7b52454441435445447d == logfusc.Secret[string]{REDACTED}\n```\n\n### Log anything, anywhere\n\n`logfusc.Secret` redacts your secrets when marshaled to a variety of formats, so\nyou can pass complete structs to your logger without worrying about leaking\nsensitive data. No more manual redaction. No configuration. No leaks.\n\n```go\ntype Universe struct {\n    SecretOfLife logfusc.Secret[int] `json:\"secret_of_life\"`\n}\n\nfunc main() {\n  universe := Universe{\n      SecretOfLife: logfusc.NewSecret(42),\n  }\n\n  b, _ := json.Marshal(universe)\n\n  log.Println(string(b))\n}\n\n// =\u003e {\"name\":\"alice\",\"secret_of_life\":\"logfusc.Secret[int]{REDACTED}\"}\n```\n\nSo far, `Secret` satisfies:\n- `json.Marshaler` (tested with both `encoding/json` and [json-iterator](https://github.com/json-iterator/go))\n- More coming soon! Too slow for you? Why not contribute?\n\n### Decode directly to logfusc.Secret\n\nProtect secrets at the boundaries of your service by decoding them directly into\n`logfusc.Secret`.\n\n```go\ntype RegisterRequest struct {\n  Email string `json:\"email\"`\n  Password logfusc.Secret[string] `json:\"password\"`\n}\n\nfunc Register(w http.ResponseWriter, r *http.Request) {\n  var req RegisterRequest\n  _ = json.NewDecoder(r.Body).Decode(\u0026req)\n  fmt.Println(req.Password)\n  fmt.Println(req.Password.Expose())\n}\n\n// =\u003e logfusc.Secret[string]{REDACTED}\n//    password\n```\n\nSo far, `Secret` satisfies:\n- `json.Unmarshaler`\n- More coming soon! Too slow for you? Why not contribute?\n\n### Use secrets with intention\n\n`Secret` encourages you to log often and trace **everything** in the knowledge that\nyour secrets are safe. That doesn't stop you working with sensitive data,\nbut you have to do it *deliberately*.\n\n```go\nsecret := logfusc.NewSecret(\"PEM string\")\nlog.Println(secret.Expose())\n\n// =\u003e PEM string\n```\n\n## Compatibility\n\nWhen logged as a standalone object or as an exported struct field,\n`logfusc.Secret` will work as described with all sane logging libraries.\n\nFor your peace of mind, `logfusc.Secret` has been explicitly tested for\ncompatibility with the following loggers:\n- `log`\n- `logrus`\n- `zap`\n- `zerolog`\n- More compatibility tests coming soon! Too slow for you? Why not contribute?\n\n### ⚠️ Caution ⚠️\nThe standard library `fmt` package and any third-party packages that use reflection\nto deeply print structs __DO NOT__ respect `fmt.Stringer` or `fmt.GoStringer`\nimplementations for unexported struct fields.\n\nIf a `logfusc.Secret` is logged as part of a struct with unexported fields, it\n__will__ be logged in plain text.\n\nAlternatively:\n* Use `logfusc.Secret` only in exported struct fields.\n* Define custom `fmt.Stringer` and `fmt.GoStringer` implementations for structs\n  that contain unexported `logfusc.Secret` fields, invoking `Secret.String()` or\n  `Secret.GoString()` manually for these fields.\n* Use [go-spew](https://github.com/davecgh/go-spew) instead of `fmt`, which deeply prints structs without reflection,\n  respecting `fmt.Stringer` and `fmt.GoStringer` implementations for unexported\n  fields.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fangusgmorrison%2Flogfusc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fangusgmorrison%2Flogfusc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fangusgmorrison%2Flogfusc/lists"}