{"id":13414037,"url":"https://github.com/esurdam/go-sophos","last_synced_at":"2026-01-12T03:04:22.535Z","repository":{"id":34490553,"uuid":"147460369","full_name":"esurdam/go-sophos","owner":"esurdam","description":"Sophos UTM 9 REST API Client in Golang","archived":false,"fork":false,"pushed_at":"2022-05-06T02:42:29.000Z","size":1186,"stargazers_count":12,"open_issues_count":0,"forks_count":4,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-07-31T20:53:19.919Z","etag":null,"topics":["golang","golang-library","sophos","sophos-utm","utm"],"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/esurdam.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-09-05T04:37:25.000Z","updated_at":"2023-08-18T04:17:28.000Z","dependencies_parsed_at":"2022-08-08T12:30:20.872Z","dependency_job_id":null,"html_url":"https://github.com/esurdam/go-sophos","commit_stats":null,"previous_names":[],"tags_count":13,"template":false,"template_full_name":null,"purl":"pkg:github/esurdam/go-sophos","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/esurdam%2Fgo-sophos","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/esurdam%2Fgo-sophos/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/esurdam%2Fgo-sophos/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/esurdam%2Fgo-sophos/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/esurdam","download_url":"https://codeload.github.com/esurdam/go-sophos/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/esurdam%2Fgo-sophos/sbom","scorecard":{"id":383458,"data":{"date":"2025-08-11","repo":{"name":"github.com/esurdam/go-sophos","commit":"191de4d9e2f9a6234969a3a3e3103deb5915cc6f"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.5,"checks":[{"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":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/go.yml:1","Info: no jobLevel write permissions found"],"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":"Code-Review","score":0,"reason":"Found 0/26 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":"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":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","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":"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":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/go.yml:20: update your workflow using https://app.stepsecurity.io/secureworkflow/esurdam/go-sophos/go.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/go.yml:23: update your workflow using https://app.stepsecurity.io/secureworkflow/esurdam/go-sophos/go.yml/master?enable=pin","Warn: downloadThenRun not pinned by hash: .github/workflows/go.yml:26","Info:   0 out of   2 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   1 downloadThenRun dependencies pinned"],"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":"CII-Best-Practices","score":2,"reason":"badge detected: InProgress","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":"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":"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":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 8 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"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-18T16:00:43.535Z","repository_id":34490553,"created_at":"2025-08-18T16:00:43.536Z","updated_at":"2025-08-18T16:00:43.536Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28332868,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-12T00:36:25.062Z","status":"online","status_checked_at":"2026-01-12T02:00:08.677Z","response_time":98,"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":["golang","golang-library","sophos","sophos-utm","utm"],"created_at":"2024-07-30T20:01:55.951Z","updated_at":"2026-01-12T03:04:22.507Z","avatar_url":"https://github.com/esurdam.png","language":"Go","funding_links":[],"categories":["Third-party APIs","第三方api","第三方API`第三方API 汇总`","第三方API","Utility"],"sub_categories":["Utility/Miscellaneous","实用程序/Miscellaneous","HTTP Clients","查询语","交流","Fail injection"],"readme":"\n# go-sophos\n\n[![Documentation](https://godoc.org/github.com/esurdam/go-sophos?status.svg)](http://godoc.org/github.com/esurdam/go-sophos)\n[![Go Report Card](https://goreportcard.com/badge/github.com/esurdam/go-sophos)](https://goreportcard.com/report/github.com/esurdam/go-sophos)\n[![codecov](https://codecov.io/gh/esurdam/go-sophos/branch/master/graph/badge.svg)](https://codecov.io/gh/esurdam/go-sophos)\n![go workflow](https://github.com/esurdam/go-sophos/actions/workflows/go.yml/badge.svg)\n[![MIT License](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/esurdam/go-sophos/blob/master/LICENSE)\n[![Mentioned in Awesome Go](https://awesome.re/mentioned-badge.svg)](https://github.com/avelino/awesome-go/#third-party-apis)\n\nA [Sophos UTM REST API client](https://www.sophos.com/en-us/medialibrary/PDFs/documentation/UTMonAWS/Sophos-UTM-RESTful-API.pdf?la=en) for Go with zero dependencies. \n\n## Prerequisites\n\nThe Sophos UTM REST API must be enabled in Administrator settings.\n\nFamiliarity with the [Sophos docs](https://www.sophos.com/en-us/medialibrary/PDFs/documentation/UTMonAWS/Sophos-UTM-RESTful-API.pdf?la=en).\n\nAPI types and functions are [generated](#generating-types) and versioned against UTM's declared Restd version.\n\n## Usage\n\nAPI is stable as of 0.1.0\n\n```bash\ngo get github.com/esurdam/go-sophos\n```\n\nCreate a client:\n\n```go\nimport \"github.com/esurdam/go-sophos\"\n\n// All Options passed on initialize will be applied to all subsequent calls\nclient, _ := sophos.New(\n    \"192.168.0.1:4848\", \n    sophos.WithBasicAuth(\"user\", \"pass\"),\n)\n```\n\nRequesting the current port of the WebAdmin (see [Nodes](#nodes) for more usage):\n```go\nimport \"github.com/esurdam/go-sophos\"\n\nclient, _ := sophos.New(\n    \"192.168.0.1:4848\", \n    sophos.WithApiToken(\"abCDEFghIjklMNOPQkwSnwbutCpHdjQz\"),\n)\nres, _ := client.Get(\"/api/nodes/webadmin.port\")\n\nvar port int\nres.MarshalTo(\u0026port)\nfmt.Println(port)\n// Output: 4848\n```\n\n### Nodes\n\nNodes are interacted with using pacakage level functions:\n\n```go\nimport \"github.com/esurdam/go-sophos/api/v1.3.0/nodes\"\n\nv, err := nodes.GetWebadminPort(client)\nfmt.Println(v)\n// Output: 4848\n\nerr = nodes.UpdateWebadminPort(client, 4444)\n```\n\nOr as struct types with syntactic sugar around the functions, as represented by the [Node](nodes.go#L24) interface:\n\n```go\nimport \"github.com/esurdam/go-sophos/api/v1.3.0/nodes\"\n\nvar wap nodes.WebadminPort\nerr := wap.Get(client)\nfmt.Println(wap.Value)\n// Output: 4848\n\nwap.Value = 4444\nerr = wap.Update(client)\n\n```\n\nYou can get the whole UTM node tree as an [object](#objects) as well:\n\n```go\nimport \"github.com/esurdam/go-sophos/api/v1.3.0/objects\"\n\nvar nodes objects.Nodes\n_ := client.GetObject(\u0026nodes)\n\n// active Ips\nnodes.LicensingActiveIps \n```\n\n### Objects\n\nEach file in the [objects](api/v1.3.0/objects) dir represents an [Endpoint](nodes.go#L7) generated from a [Definition](definition.go) and contains its generated Objects.\n\nObjects implement the [RestObject](nodes.go#L46) interface:\n\n```go\nimport \"github.com/esurdam/go-sophos/api/v1.3.0/objects\"\n\nvar dns objects.Dns\nerr := client.GetObject(\u0026dns)\n```\n\nNotice that some objects are pluralized and only implement the [RestGetter](nodes.go#L56) interface:\n```go\nimport \"github.com/esurdam/go-sophos/api/v1.3.0/objects\"\n\nvar ss objects.DnsRoutes\n_ = client.GetObject(\u0026ss)\n\n// Each individual DnsRoute is therefore a RestObject\nfor _, s := range ss {\n    ub, _ := client.GetUsedBy(\u0026s)\n    fmt.Printf(\"DNS ROUTE: %s [%s]\\n  Used By Nodes: %v\\n  Used by Objects: %v\\n\",s.Name, s.Reference, ub.Nodes, ub.Objects)\n    // OUTPUT: DNS ROUTE: sophos.boom.local [REF_DnsRouBoomloca]\n    //             Used By Nodes: [dns.routes]\n    //             Used by Objects: []\n}\n```\n\nNote that [Endpoint](nodes.go#L2) types contain their [Definition](definition.go#L3):\n\n```go\nimport \"github.com/esurdam/go-sophos/api/v1.3.0/objects\"\n\nfmt.Printf(\"%#v\", objects.Dns{}.Definition())\n// Output: sophos.Definition{\n//  Description:\"dns\", \n//  Name:\"dns\", \n//  Link:\"/api/definitions/dns\"\n// }\n```\n\nRequesting an Endpoint's [Swag](definition.go#L29):\n\n```go\nimport \"github.com/esurdam/go-sophos/api/v1.3.0/objects\"\n\n// with sugar\nvar dns objects.Dns\nswag, _ := client.GetEndpointSwag(dns)\n\n// without sweets\nd := objects.Dns{}.Definition()\nswag, _ := d.GetSwag(client)\n```\n\n\n## Examples\n\nExamples from [Sophos docs](https://www.sophos.com/en-us/medialibrary/PDFs/documentation/UTMonAWS/Sophos-UTM-RESTful-API.pdf?la=en).\n\nDeleting a packet filter rule with reference `REF_PacPacXYZ`:\n\nThis example uses the `X-Restd-Err-Ack: all` header to automatically approve the deletion of the object:\n```go\nimport \"github.com/esurdam/go-sophos\"\n\nclient, _ := sophos.New(\n    \"192.168.0.1:4848\", \n    sophos.WithBasicAuth(\"user\", \"pass\"),\n)\n\n_, err := client.Delete(\n    \"api/objects/packetfilter/packetfilter/REF_PacPacXYZ\", \n    sophos.WithSessionClose, \n    sophos.AutoResolveErrsMode,\n)\n```\n\nThe same as above but using objects: [[example](examples/delete_packetfilter.go)]\n\n```go\nimport \"github.com/esurdam/go-sophos\"\nimport \"github.com/esurdam/go-sophos/api/v1.3.0/objects\"\n\nclient, _ := sophos.New(\n    \"192.168.0.1:4848\", \n    sophos.WithBasicAuth(\"user\", \"pass\"),\n)\n\n// object knows api route\npf := objects.PacketfilterPacketfilter{\n\tReference: \"REF_PacPacXYZ\"\n}\n\nerr := client.DeleteObject(\u0026pf, \n\tsophos.WithSessionClose, \n\tsophos.AutoResolveErrsMode\n)\n```\n\nCreating a PacketFilter: [[example](examples/create_packetfilter.go)]\n\n```go\nimport \"github.com/esurdam/go-sophos\"\nimport \"github.com/esurdam/go-sophos/api/v1.3.0/objects\"\n\nclient, _ := sophos.New(\n    \"192.168.0.1:4848\", \n    sophos.WithBasicAuth(\"user\", \"pass\"),\n)\n\npf := objects.PacketfilterPacketfilter{\n    Action:       \"accept\",\n    Destinations: []string{sophos.RefNetworkAny},\n    Direction:    \"in\",\n    Log:          true,\n    Services:     []string{sophos.RefServiceAny},\n    Sources:      []string{sophos.RefNetworkAny},\n    Status:       true,\n}\n\nerr := client.PostObject(\u0026pf, \n\tsophos.WithRestdInsert(\"packetfilter.rules\", 0), \n\tsophos.WithSessionClose,\n)\n\n// successful creation will have unmarshalleed the Response\npf.Reference  \n```\n\nErrors\n\n```go\nif err != nil {\n    // for modifying requests (PATCH, PUT, POST, DELETE), err returned may be of type *sophos.Errors\n    // see client.Do and Response type for how errors are parsed\n    err.(*sophos.Errors).Error() == err.Error()\n    sophos.IsFatalErr(err) == err.(*sophos.Errors).IsFatal()\n    \n    // view each individual error\n    for _, e := range *err.(*sophos.Errors) {\n    \te.Error() \n    \te.IsFatal()\n    }\n}\n```\n\n## Generating Types\n\nSophos types are automatically generated using [bin/gen.go](bin/gen.go) which queries the UTM `api/definitions` path to generate all the files in the [api](api/v1.3.0) which contain structs and helper functions corresponding to UTM API definitions.\n\nGenerated pacakages are versioned, feel free to generate against an older version and submit.\n\n```bash\nexport ENDPOINT=192.168.0.1:4848\nexport TOKEN=abcde1234\n\nmake\n```\n\n## Testing\n\n```bash\nmake test\n```\n\n## Todo\n- [x] Create all unknown types (not returned from UTM) from their swagger definitions\n- [x] Respond with Errors to ObjectClient functions for caller inspection\n- [x] Finish adding all example from [Sophos docs](https://www.sophos.com/en-us/medialibrary/PDFs/documentation/UTMonAWS/Sophos-UTM-RESTful-API.pdf?la=en)\n- [x] Add [nodes](nodes.go) examples in README\n- [x] Add PUT, POST, PATCH and DELETE methods to generated objects\n- [x] Create a wrapper Client for REST objects `client.Get(\u0026nodes)` \n\n## Contributing\n\nPlease read [CONTRIBUTING.md](https://gist.github.com/PurpleBooth/b24679402957c63ec426) for details on our code of conduct, and the process for submitting pull requests to us.\n\n## License\n\nThis project is licensed under the MIT License - see the [LICENSE.md](LICENSE) file for details\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fesurdam%2Fgo-sophos","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fesurdam%2Fgo-sophos","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fesurdam%2Fgo-sophos/lists"}