{"id":37213657,"url":"https://github.com/reeflective/team","last_synced_at":"2026-01-15T00:40:00.333Z","repository":{"id":178453827,"uuid":"661757493","full_name":"reeflective/team","owner":"reeflective","description":"Embedded, small and composable  Zero-Trust Teamserver made for collaborative Go programs or CLI applications.","archived":false,"fork":false,"pushed_at":"2025-07-10T05:30:01.000Z","size":8377,"stargazers_count":13,"open_issues_count":0,"forks_count":2,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-10-11T02:37:51.981Z","etag":null,"topics":["cli","client-server","golang","teamserver"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/reeflective.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,"zenodo":null}},"created_at":"2023-07-03T15:18:10.000Z","updated_at":"2025-07-10T05:30:05.000Z","dependencies_parsed_at":"2025-05-05T12:21:36.511Z","dependency_job_id":"6e81a233-a8b8-4d54-8a4f-6926caf0ac5b","html_url":"https://github.com/reeflective/team","commit_stats":null,"previous_names":["reeflective/team"],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/reeflective/team","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/reeflective%2Fteam","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/reeflective%2Fteam/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/reeflective%2Fteam/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/reeflective%2Fteam/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/reeflective","download_url":"https://codeload.github.com/reeflective/team/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/reeflective%2Fteam/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28439901,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-15T00:34:46.850Z","status":"ssl_error","status_checked_at":"2026-01-15T00:34:46.551Z","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":["cli","client-server","golang","teamserver"],"created_at":"2026-01-15T00:39:59.772Z","updated_at":"2026-01-15T00:40:00.317Z","avatar_url":"https://github.com/reeflective.png","language":"Go","readme":"\n\u003cdiv align=\"center\"\u003e\n  \u003cbr\u003e \u003ch1\u003e Team \u003c/h1\u003e\n\n  \u003cp\u003e  Transform any Go program into a client of itself, remotely or locally.  \u003c/p\u003e\n  \u003cp\u003e  Use, manage teamservers and clients with code, with their CLI, or both.  \u003c/p\u003e\n\u003c/div\u003e\n\n\n\u003c!-- Badges --\u003e\n\u003c!-- Assuming the majority of them being written in Go, most of the badges below --\u003e\n\u003c!-- Replace the repo name: :%s/reeflective\\/template/reeflective\\/repo/g --\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://github.com/reeflective/team/actions/workflows/go.yml\"\u003e\n    \u003cimg src=\"https://github.com/reeflective/team/actions/workflows/go.yml/badge.svg?branch=main\"\n      alt=\"Github Actions (workflows)\" /\u003e\n  \u003c/a\u003e\n\n  \u003ca href=\"https://github.com/reeflective/team\"\u003e\n    \u003cimg src=\"https://img.shields.io/github/go-mod/go-version/reeflective/team.svg\"\n      alt=\"Go module version\" /\u003e\n  \u003c/a\u003e\n\n  \u003ca href=\"https://pkg.go.dev/github.com/reeflective/team\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/godoc-reference-blue.svg\"\n      alt=\"GoDoc reference\" /\u003e\n  \u003c/a\u003e\n\n  \u003ca href=\"https://goreportcard.com/report/github.com/reeflective/team\"\u003e\n    \u003cimg src=\"https://goreportcard.com/badge/github.com/reeflective/team\"\n      alt=\"Go Report Card\" /\u003e\n  \u003c/a\u003e\n\n  \u003ca href=\"https://codecov.io/gh/reeflective/team\"\u003e\n    \u003cimg src=\"https://codecov.io/gh/reeflective/team/branch/main/graph/badge.svg\"\n      alt=\"codecov\" /\u003e\n  \u003c/a\u003e\n\n  \u003ca href=\"https://opensource.org/licenses/BSD-3-Clause\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/License-BSD_3--Clause-blue.svg\"\n      alt=\"License: BSD-3\" /\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\n\n-----\n## Summary\n\nThe `reeflective/team` library provides a small toolset for arbitrary programs (and especially those\ncontrolled in more or less interactive ways) to collaborate together by acting as clients and\nservers of each others, as part of a team. Teams being made of players (humans _and_ their tools),\nthe library focuses on offering a toolset for \"human teaming\": that is, treating software tools that\nare either _teamclients_ or _teamservers_ of others, within a defined -generally restricted- team of\nusers, which shall generally be strictly and securely authenticated.\n\n-----\n## CLI (Users)\n\nThe following extracts assume a program binary named `teamserver`, which is simply the root command\nof the server-side team code. In this case therefore, the binary program only purpose its to be a\nteamserver, with no application-specific logic, (and is therefore quite useless on its own).\nFor example, if your application `cracker` makes use of a teamserver/client, all the following\ncommands would look like `cracker teamserver daemon`, `cracker teamserver client users`, etc:\n```\n$ teamserver\nManage the application server-side teamserver and users\n\nUsage:\n  teamserver [command]\n\nteamserver control\n  client      Client-only teamserver commands (import configs, show users, etc)\n  close       Close a listener and remove it from persistent ones if it's one\n  daemon      Start the teamserver in daemon mode (blocking)\n  listen      Start a teamserver listener (non-blocking)\n  status      Show the status of the teamserver (listeners, configurations, health...)\n  systemd     Print a systemd unit file for the application teamserver, with options\n\nuser management\n  delete      Remove a user from the teamserver, and revoke all its current tokens\n  export      Export a Certificate Authority file containing the teamserver users\n  import      Import a certificate Authority file containing teamserver users\n  user        Create a user for this teamserver and generate its client configuration file\n```\n\nIn this example, this program comes with a client-only binary counterpart, `teamclient`. The latter \ndoes not include any team server-specific code, and has therefore a much smaller command set:\n```\n$ teamclient\nClient-only teamserver commands (import configs, show users, etc)\n\nUsage:\n  teamclient [command]\n\nAvailable Commands:\n  import      Import a teamserver client configuration file for teamserver\n  users       Display a table of teamserver users and their status\n  version     Print teamserver client version\n```\n\nWith these example binaries at hand, below are some examples of workflows.\nStarting with the `teamserver` binary (which might be under access/control of a team admin):\n``` bash\n# 1 - Generate a user for a local teamserver, and import users from a file.\nteamserver user --name Michael --host localhost\nteamserver import ~/.other_app/teamserver/certs/other_app_user-ca-cert.teamserver.pem\n\n# 2 - Start some teamserver listeners, then start the teamserver daemon (blocking).\n# Use the application-defined default port in the first call, and instruct the server\n# to start the listeners automatically when used in daemon mode with --persistent.\nteamserver listen --host localhost --persistent \nteamserver listen --host 172.10.0.10 --port 32333 --persistent\nteamserver status                                                   # Prints the saved listeners, configured loggers, databases, etc.\nteamserver daemon --host localhost --port 31337                     # Blocking: serves all persistent listeners and a main one at localhost:31337\n\n# 3 - Export and enable a systemd service configuration for the teamserver.\nteamserver systemd                                                  # Use default host, port and listener stacks. \nteamserver systemd --host localhost --binpath /path/to/teamserver   # Specify binary path.\nteamserver systemd --user --save ~/teamserver.service               # Print to file instead of stdout.\n\n# 4 - Import the \"remote\" administrator configuration for (1), and use it.\nteamserver client import ~/Michael_localhost.teamclient.cfg \nteamserver client version                                   # Print the client and the server version information.\nteamserver client users                                     # Print all users registered to the teamserver and their status.\n\n# 5 - Quality of life\nteamserver _carapace \u003cshell\u003e # Source detailed the completion engine for the teamserver.\n```\n\nContinuing the `teamclient` binary (which is available to all users' tool in the team):\n```bash\n# Example 1 - Import a remote teamserver configuration file given by a team administrator.\nteamclient import ~/Michael_localhost.teamclient.cfg\n\n# Example 2 - Query the server for its information.\nteamclient users\nteamclient version\n```\n\n-----\n## Components \u0026 Terms\n\nThe result consists in 2 Go packages (`client` and `server`) for programs needing to act as:\n- A **Team client**: a program, or one of its components, that needs to rely on a \"remote\" program peer\n  to serve some functionality that is available to a team of users' tools. The program acting as a\n  _teamclient_ may do so for things as simple as sending a message to the team, or as complicated as a\n  compiler backend with which multiple client programs can send data to process and build.\n- A **Team server**: The remote, server-side counterpart of the software teamclient. Again, the\n  teamserver can be doing anything, from simply notifying users' teamclient connections to all the team\n  all the way to handling very complex and resource-hungry tasks that can only be ran on a server host.\n\nThroughout this library and its documentation, various words are repeatedly employed:\n- _teamclient_ refers to either the client-specific toolset provided by this library\n  (`team/client.Client` core type) or the software making use of this teamclient code.\n- _teamserver_ refers to either the server-specific toolset provided to make a program serve its\n  functionality remotely, or to the tools embedding this code in order to do so.\n- _team tool/s_ might be used to refer to programs using either or all of the library components at\n  large.\n\n-----\n## API (Developers)\n\nThe teamclient and teamserver APIs are designed with several things in mind as well:\n- While users are free to use their tools teamclients/servers within the bounds of the provided\n  command-line interface tree (`teamserver` and `teamclient` commands), the developers using the \n  library have access to a slightly larger API, especially with regards to \"selection strategies\"\n  (grossly, the way tools' teamclients choose their remote teamservers before connecting to them).\n  This is equivalent of saying that tools developers should have identified 70% of all different\n  scenarios/valid operation mode for their tools, and program their teamclients accounting for this,\n  but let the users decide of the remaining 30% when using the tools teamclient/server CLI commands.\n- The library makes it easy to embed a teamclient or a teamserver in existing codebases, or easy to \n  include it in the ones who will need it in the future. In any case, importing and using a default\n  teamclient/teamserver should fit into a couple of function calls at most.\n- To provide a documented code base, with a concise naming and programming model which allows equally\n  well to use default teamclient backends or to partially/fully reimplement different layers.\n\nBelow is the simplest, shortest example of the above's `teamserver` binary `main()` function:\n```go\n// Generate a teamserver, without any specific transport/RPC backend.\n// Such backends are only needed when the teamserver serves remote clients.\nteamserver, err := server.New(\"teamserver\")\n\n// Generate a tree of server-side commands: this tree also has client-only\n// commands as a subcommand \"client\" of the \"teamserver\" command root here.\nserverCmds := commands.Generate(teamserver, teamserver.Self())\n\n// Run the teamserver CLI.\nserverCmds.Execute()\n```\n\nAnother slightly more complex example, involving a gRPC transport/RPC backend:\n```go\n// The examples directory has a default teamserver listener backend.\ngTeamserver := grpc.NewListener()\n\n// Create a new teamserver, register the gRPC backend with it.\n// All gRPC teamclients will be able to connect to our teamserver.\nteamserver, err := server.New(\"teamserver\", server.WithListener(gTeamserver))\n\n// Since our teamserver offers its functionality through a gRPC layer,\n// our teamclients must have the corresponding client-side RPC client backend.\n// Create an in-memory gRPC teamclient backend for the server to serve itself.\ngTeamclient := grpc.NewClientFrom(gTeamserver)\n\n// Create a new teamclient, registering the gRPC backend to it.\nteamclient := teamserver.Self(client.WithDialer(gTeamclient))\n\n// Generate the commands for the teamserver.\nserverCmds := commands.Generate(teamserver, teamclient)\n\n// Run any of the commands.\nserverCmds.Execute()\n```\n\nSome additional and preliminary/example notes about the codebase:\n- All errors returned by the API are always logged before return (with configured log behavior).\n- Interactions with the filesystem restrained until they need to happen.\n- The default database is a pure Go file-based sqlite db, which can be configured to run in memory.\n- Unless absolutely needed or specified otherwise, return all critical errors instead of log\n  fatal/panicking (exception made of the certificate infrastructure which absolutely needs to work\n  for security reasons).\n- Exception made of the `teamserver daemon` command related `server.ServeDaemon` function, all API\n  functions and interface methods are non-blocking. Mentions of this are found throughout the\n  code documentation when needed.\n- Loggers offered by the teamclient/server cores are never nil, and will log to both stdout (above\n  warning level) and to default files (above info level) if no custom logger is passed to them.\n  If such a custom logger is given, team clients/servers won't log to stdout or their default files.\n\nPlease see the [example](https://github.com/reeflective/team/tree/main/example) directory for all client/server entrypoint examples.\n\n-----\n## Documentation\n\n- Go code documentation is available at the [Godoc website](https://pkg.go.dev/github.com/reeflective/team).\n- Client and server documentation can be found in the [directories section](https://pkg.go.dev/github.com/reeflective/team#section-directories) of the Go documentation.\n- The `example/` subdirectories also include documentation for their own code, and should provide\na good introduction to this library usage. \n\n-----\n## Background\n\nThe project originates from the refactoring of a security-oriented tool that used this approach to\nclearly segregate client and server binary code (the former's not needing most of the latter's).\nBesides, the large exposure of the said-tool to the CLI prompted the author of the\n`reeflective/team` library to rethink how the notion of \"collaborative programs\" could be approached\nand explored from different viewpoints: distinguishing between the tools' developers, and their\nusers. After having to reuse this core code for other projects, the idea appeared to extract the\nrelevant parts and to restructure and repackage them behind coherent interfaces (API and CLI).\n\nThe client-server paradigm is an ubiquitous concept in computer science. Equally large and common is\nthe problem of building software that _collaborates_ easily with other peer programs. Although\nwriting collaborative software seems to be the daily task of many engineers around the world,\nsucceedingly and easily doing so in big programs as well as in smaller ones is not more easily done\nthan said. Difficulty still increases -and keeping in mind that humans use software and not the\ninverse- when programs must enhance the capacity of humans to collaborate while not restricting the\nnumber of ways they can do so, for small tasks as well as for complex ones.\n\n-----\n## Principles, Constraints \u0026 Features\n\nThe library rests on several principles, constraints and ideas to fulfill its intended purpose:\n- The library's sole aim is to **make most programs able to collaborate together** under the\n  paradigm of team clients and team servers, and to do so while ensuring performance, coherence,\n  ease of use and security of all processes and workflows involved. This, under the _separate\n  viewpoints_ of tool development, enhancement and usage.\n- Ensure a **working-by-default toolset**, assuming that the time spent on any tool's configuration\n  is inversely proportional to its usage. Emphasis on this aspect should apply equally well to team\n  tools' users and developers.\n- Ensure the **full, secure and reliable authentication of all team clients and servers'\n  interactions**, by using certificate-based communication encryption and user authentication, _aka_\n  \"zero-trust\" model. Related and equally important, ensure the various team toolset interfaces\n  provide for easy and secure usage of their host tools.\n- **Accomodate for the needs of developers to use more specific components**, at times or at points,\n  while not hampering on the working-by-default aspects of the team client/server toolset. Examples\n  include replacing parts or all of the transport, RPC, loggers, database and filesystem\n  backends.\n- To that effect, the library offers **different interfaces to its functionality**: an API (Go code)\n  provides developers a working-by-default, simple and powerful way to instruct their software how \n  to collaborate with peers, and a CLI, for users to operate their team tools, manage their related \n  team configurations with ease, with a featured command-line tree to embed anywhere.\n- Ensure that team client/server functionality can be **easily integrated in automated workflows**: \n  this is done by offering clear code/execution paths and behaviors, for both users and developers,\n  and by providing commands and functions to ease deployment of said tools.\n\n-----\n## Differences with the Hashicorp Go plugin system\n\nAt first glance, different and not much related to our current topic is the equally large problem of\ndynamic code loading and execution for arbitrary programs. In the spectrum of major programming\nlanguages, various approaches have been taken to tackle the dynamic linking, loading and execution\nproblem, with interpreted languages offering the most common solutioning approach to this.\n\nThe Go language (and many other compiled languages that do not encourage dynamic linking for that\nmatter) has to deal with the problem through other means, the first of which simply being the\nadoption of different architectural designs in the first place (eg. \"microservices\"). Another path\nhas been the \"plugin system\" for emulating the dynamic workflows of interpreted languages, of which\nthe most widely used attempt being the [Hashicorp plugin\nsystem](https://github.com/hashicorp/go-plugin), which entirely rests on an (g)RPC backend.\n\nConsequently, differences and similarities can be resumed as follows:\n- The **Hashicorp plugins only support \"remote\" plugins** in that each plugin must be a different\n  binary. Although those plugins seem to be executed \"in-memory\", they are not. On the contrary,\n  the `reeflective/team` clients and servers can (should, and will) be used both in memory and\n  remotely (here remotely means as a distinct subprocess: actual network location is irrelevant).\n- The purpose of the `reeflective/team` library is **not** to emulate dynamic code execution behavior.\n  Rather, its intent is to make programs that should or might be better used as servers to several\n  clients to act as such easily and securely in many different scenarios.\n- The **Hashicorp plugins are by essence restrained to an API problem**, and while the `team` library\n  is equally (but not mandatorily or exclusively) about interactive usage of arbitrary programs.\n- **The Hashicorp plugin relies mandatorily (since it's built on) a gRPC transport backend**. While\n  gRPC is a very sensible choice for many reasons (and is therefore used for the default example\n  backend in `example/transports/`), the `team` library does not force library users to use a given\n  transport/RPC backend, nor even to use one. Again, this would be beyond the library scope, but\n  what is in scope is the capacity of this library to interface with or use different transports.\n- Finally, the Hashicorp plugins are not aware of any concept of users as they are considered by\n  the team library, although both use certificate-based connections. However, `team` promotes and\n  makes easy to use mutually authenticated (Mutual TLS) connections (see the default gRPC example \n  backend). Related to this, teamservers integrate loggers and a database to store working data.\n\n-----\n## Status\n\nThe Command-Line and Application-Programming Interfaces of this library are unlikely to change\nmuch in the future, and should be considered mostly stable. These might grow a little bit, but\nwill not shrink, as they been already designed to be as minimal as they could be.\n\nIn particular, `client.Options` and `server.Options` APIs might grow, so that new features/behaviors\ncan be integrated without the need for the teamclients and teamservers types APIs to change.\n\nThe section **Possible Enhancements** below includes 9 points, which should grossly be equal\nto 9 minor releases (`0.1.0`, `0.2.0`, `0.3.0`, etc...), ending up in `v1.0.0`.\n\n- Please open a PR or an issue if you face any bug, it will be promptly resolved.\n- New features and/or PRs are welcome if they are likely to be useful to most users.\n\n-----\n## Possible enhancements\n\nThe list below is not an indication on the roadmap of this repository, but should be viewed as\nthings the author of this library would be very glad to merge contributions for, or get ideas. \nThis teamserver library aims to remain small, with a precise behavior and role.\nOverall, contributions and ideas should revolve around strenghening its core/transport code\nor around enhancing its interoperability with as much Go code/programs as possible.\n\n- [ ] Add support for encrypted sqlite by default.\n- [ ] Replace logrus entirely and restructure behind a single package used by both client/server.\n- [ ] Implement tests for most sensitive paths (certificates management, database functioning, etc)\n\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Freeflective%2Fteam","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Freeflective%2Fteam","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Freeflective%2Fteam/lists"}