{"id":13582530,"url":"https://github.com/osquery/osquery-go","last_synced_at":"2025-06-11T11:20:47.889Z","repository":{"id":41993899,"uuid":"90204769","full_name":"osquery/osquery-go","owner":"osquery","description":"Go bindings for osquery","archived":false,"fork":false,"pushed_at":"2025-01-31T15:45:56.000Z","size":183,"stargazers_count":394,"open_issues_count":10,"forks_count":80,"subscribers_count":21,"default_branch":"master","last_synced_at":"2025-02-03T00:01:57.100Z","etag":null,"topics":["golang","osquery","thrift"],"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/osquery.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","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-05-04T00:24:42.000Z","updated_at":"2025-01-31T15:46:01.000Z","dependencies_parsed_at":"2023-01-29T21:46:33.063Z","dependency_job_id":"b66b005e-4073-4557-aeb6-617303c21e98","html_url":"https://github.com/osquery/osquery-go","commit_stats":{"total_commits":63,"total_committers":14,"mean_commits":4.5,"dds":0.5238095238095238,"last_synced_commit":"4e1f83012b42aecd30a01e31b3c2a72347719019"},"previous_names":["kolide/osquery-go"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/osquery%2Fosquery-go","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/osquery%2Fosquery-go/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/osquery%2Fosquery-go/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/osquery%2Fosquery-go/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/osquery","download_url":"https://codeload.github.com/osquery/osquery-go/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/osquery%2Fosquery-go/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259253756,"owners_count":22829151,"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":["golang","osquery","thrift"],"created_at":"2024-08-01T15:02:48.093Z","updated_at":"2025-06-11T11:20:47.849Z","avatar_url":"https://github.com/osquery.png","language":"Go","readme":"# osquery-go\n\n[![GoDoc](https://godoc.org/github.com/osquery/osquery-go?status.svg)](http://godoc.org/github.com/osquery/osquery-go)\n\n[osquery](https://github.com/facebook/osquery) exposes an operating system as a high-performance relational database. This allows you to write SQL-based queries to explore operating system data. With osquery, SQL tables represent abstract concepts such as running processes, loaded kernel modules, open network connections, browser plugins, hardware events or file hashes.\n\nIf you're interested in learning more about osquery, visit the [GitHub project](https://github.com/facebook/osquery), the [website](https://osquery.io), and the [users guide](https://osquery.readthedocs.io).\n\n## What is osquery-go?\n\nIn osquery, SQL tables, configuration retrieval, log handling, etc. are implemented via a robust plugin and extensions API. This project contains Go bindings for creating osquery extensions in Go. To create an extension, you must create an executable binary which instantiates an `ExtensionManagerServer` and registers the plugins that you would like to be added to osquery. You can then have osquery load the extension in your desired context (ie: in a long running instance of `osqueryd` or during an interactive query session with `osqueryi`). For more information about how this process works at a lower level, see the osquery [wiki](https://osquery.readthedocs.io/en/latest/development/osquery-sdk/).\n\n## Install\n\nThis library is compatible with Go Modules. To install:\n\n``` go\ngo get github.com/osquery/osquery-go\n```\n\n## Using the library\n\n### Creating a new osquery table\n\nIf you want to create a custom osquery table in Go, you'll need to write an extension which registers the implementation of your table. Consider the following Go program:\n\n\n```go\npackage main\n\nimport (\n\t\"context\"\n\t\"log\"\n\t\"os\"\n\t\"flag\"\n\n\t\"github.com/osquery/osquery-go\"\n\t\"github.com/osquery/osquery-go/plugin/table\"\n)\n\nfunc main() {\n\tsocket := flag.String(\"socket\", \"\", \"Path to osquery socket file\")\n\tflag.Parse()\n\tif *socket == \"\" {\n\t\tlog.Fatalf(`Usage: %s --socket SOCKET_PATH`, os.Args[0])\n\t}\n\n\tserver, err := osquery.NewExtensionManagerServer(\"foobar\", *socket)\n\tif err != nil {\n\t\tlog.Fatalf(\"Error creating extension: %s\\n\", err)\n\t}\n\n\t// Create and register a new table plugin with the server.\n\t// table.NewPlugin requires the table plugin name,\n\t// a slice of Columns and a Generate function.\n\tserver.RegisterPlugin(table.NewPlugin(\"foobar\", FoobarColumns(), FoobarGenerate))\n\tif err := server.Run(); err != nil {\n\t\tlog.Fatalln(err)\n\t}\n}\n\n// FoobarColumns returns the columns that our table will return.\nfunc FoobarColumns() []table.ColumnDefinition {\n\treturn []table.ColumnDefinition{\n\t\ttable.TextColumn(\"foo\"),\n\t\ttable.TextColumn(\"baz\"),\n\t}\n}\n\n// FoobarGenerate will be called whenever the table is queried. It should return\n// a full table scan.\nfunc FoobarGenerate(ctx context.Context, queryContext table.QueryContext) ([]map[string]string, error) {\n\treturn []map[string]string{\n\t\t{\n\t\t\t\"foo\": \"bar\",\n\t\t\t\"baz\": \"baz\",\n\t\t},\n\t\t{\n\t\t\t\"foo\": \"bar\",\n\t\t\t\"baz\": \"baz\",\n\t\t},\n\t}, nil\n}\n```\n\nTo test this code, start an osquery shell and find the path of the osquery extension socket:\n\n```sql\nosqueryi --nodisable_extensions\nosquery\u003e select value from osquery_flags where name = 'extensions_socket';\n+-----------------------------------+\n| value                             |\n+-----------------------------------+\n| /Users/USERNAME/.osquery/shell.em |\n+-----------------------------------+\n```\n\nThen start the Go extension and have it communicate with osqueryi via the extension socket that you retrieved above:\n\n```bash\ngo run ./my_table_plugin.go --socket /Users/USERNAME/.osquery/shell.em\n```\n\nAlternatively, you can also autoload your extension when starting an osquery shell:\n\n```bash\ngo build -o my_table_plugin my_table_plugin.go\nosqueryi --extension /path/to/my_table_plugin\n```\n\nThis will register a table called \"foobar\". As you can see, the table will return two rows:\n\n```sql\nosquery\u003e select * from foobar;\n+-----+-----+\n| foo | baz |\n+-----+-----+\n| bar | baz |\n| bar | baz |\n+-----+-----+\nosquery\u003e\n```\n\nThis is obviously a contrived example, but it's easy to imagine the possibilities.\n\nUsing the instructions found on the [wiki](https://osquery.readthedocs.io/en/latest/development/osquery-sdk/), you can deploy your extension with an existing osquery deployment.\n\n### Creating logger and config plugins\n\nThe process required to create a config and/or logger plugin is very similar to the process outlined above for creating an osquery table. Specifically, you would create an `ExtensionManagerServer` instance in `func main()`, register your plugin and launch the extension as described above. The only difference is that the implementation of your plugin would be different. Each plugin package has a `NewPlugin` function which takes the plugin name as the first argument, followed by a list of required arguments to implement the plugin.\nFor example, consider the implementation of an example logger plugin:\n\n```go\nfunc main() {\n    // create and register the plugin\n\tserver.RegisterPlugin(logger.NewPlugin(\"example_logger\", LogString))\n}\n\nfunc LogString(ctx context.Context, typ logger.LogType, logText string) error {\n\tlog.Printf(\"%s: %s\\n\", typ, logText)\n\treturn nil\n}\n```\n\nAdditionally, consider the implementation of an example config plugin:\n\n```go\nfunc main() {\n    // create and register the plugin\n\tserver.RegisterPlugin(config.NewPlugin(\"example\", GenerateConfigs))\n}\n\nfunc GenerateConfigs(ctx context.Context) (map[string]string, error) {\n\treturn map[string]string{\n\t\t\"config1\": `\n{\n  \"options\": {\n    \"host_identifier\": \"hostname\",\n    \"schedule_splay_percent\": 10\n  },\n  \"schedule\": {\n    \"macos_kextstat\": {\n      \"query\": \"SELECT * FROM kernel_extensions;\",\n      \"interval\": 10\n    },\n    \"foobar\": {\n      \"query\": \"SELECT foo, bar, pid FROM foobar_table;\",\n      \"interval\": 600\n    }\n  }\n}\n`,\n\t}, nil\n}\n```\n\nAll of these examples and more can be found in the [examples](./examples) subdirectory of this repository.\n\n### Execute queries in Go\n\nThis library can also be used to create a Go client for the osqueryd or osqueryi's extension socket. You can use this to add the ability to performantly execute osquery queries to your Go program. Consider the following example:\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"time\"\n\n\t\"github.com/osquery/osquery-go\"\n)\n\nfunc main() {\n\tif len(os.Args) != 3 {\n\t\tlog.Fatalf(\"Usage: %s SOCKET_PATH QUERY\", os.Args[0])\n\t}\n\n\tclient, err := osquery.NewClient(os.Args[1], 10*time.Second)\n\tif err != nil {\n\t\tlog.Fatalf(\"Error creating Thrift client: %v\", err)\n\t}\n\tdefer client.Close()\n\n\tresp, err := client.Query(os.Args[2])\n\tif err != nil {\n\t\tlog.Fatalf(\"Error communicating with osqueryd: %v\",err)\n\t}\n\tif resp.Status.Code != 0 {\n\t\tlog.Fatalf(\"osqueryd returned error: %s\", resp.Status.Message)\n\t}\n\n\tfmt.Printf(\"Got results:\\n%#v\\n\", resp.Response)\n}\n```\n\n### Loading extensions with osqueryd\n\nIf you write an extension with a logger or config plugin, you'll likely want to autoload the extensions when `osqueryd` starts. `osqueryd` has a few requirements for autoloading extensions, documented on the [wiki](https://osquery.readthedocs.io/en/latest/deployment/extensions/). Here's a quick example using a logging plugin to get you started:\n\n1. Build the plugin. Make sure to add `.ext` as the file extension. It is required by osqueryd.\n```go build -o /usr/local/osquery_extensions/my_logger.ext```\n\n2. Set the correct permissions on the file and directory. If `osqueryd` runs as root, the directory for the extension must only be writable by root.\n\n```\nsudo chown -R root /usr/local/osquery_extensions/\n```\n\n3. Create an `extensions.load` file with the path of your extension.\n\n```\necho \"/usr/local/osquery_extensions/my_logger.ext\" \u003e /tmp/extensions.load\n```\n\n4. Start `osqueryd` with the `--extensions_autoload` flag.\n\n```\nsudo osqueryd --extensions_autoload=/tmp/extensions.load --logger-plugin=my_logger -verbose\n```\n\n\n## Contributing\n\nFor more information on contributing to this project, see [CONTRIBUTING.md](./CONTRIBUTING.md).\n\n## Vulnerabilities\n\nIf you find a vulnerability in this software, please email [security@kolide.co](mailto:security@kolide.co).\n","funding_links":[],"categories":["Go"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fosquery%2Fosquery-go","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fosquery%2Fosquery-go","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fosquery%2Fosquery-go/lists"}