{"id":13989843,"url":"https://github.com/opentable/hobknob","last_synced_at":"2025-07-22T11:31:54.243Z","repository":{"id":14006572,"uuid":"16708026","full_name":"opentable/hobknob","owner":"opentable","description":"Hobknob is a feature toggle front-end built on top of etcd. It allows users to create and modify feature toggles, which can then be accessed in your applications.","archived":true,"fork":false,"pushed_at":"2022-10-06T10:54:07.000Z","size":3084,"stargazers_count":97,"open_issues_count":26,"forks_count":30,"subscribers_count":15,"default_branch":"master","last_synced_at":"2025-07-14T02:58:03.145Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"JavaScript","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/opentable.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}},"created_at":"2014-02-10T20:19:24.000Z","updated_at":"2025-01-24T05:46:48.000Z","dependencies_parsed_at":"2022-08-25T03:40:25.115Z","dependency_job_id":null,"html_url":"https://github.com/opentable/hobknob","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/opentable/hobknob","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/opentable%2Fhobknob","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/opentable%2Fhobknob/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/opentable%2Fhobknob/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/opentable%2Fhobknob/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/opentable","download_url":"https://codeload.github.com/opentable/hobknob/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/opentable%2Fhobknob/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":266483788,"owners_count":23936422,"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-07-22T02:00:09.085Z","response_time":66,"last_error":null,"robots_txt_status":null,"robots_txt_updated_at":null,"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":"2024-08-09T13:02:06.824Z","updated_at":"2025-07-22T11:31:52.907Z","avatar_url":"https://github.com/opentable.png","language":"JavaScript","funding_links":[],"categories":["JavaScript"],"sub_categories":[],"readme":"# Important!\n\nThis repository is deprecated and no longer actively supported. \n\nIf you are a contributor willing to take this project over then please get in touch via [search-experience@opentable.com](mailto:search-experience@opentable.com)\n\n\u003cimg src=\"http://media.otstatic.com/img/logo-7cd459fb1da36ae8f2030a77aa098c2a.png\" style=\"width:150px;margin:0 16px -4px 0;\" alt=\"opentable logo\" title=\"OpenTable\" /\u003eHobknob\n======================\n\n[![Build Status](https://travis-ci.org/opentable/hobknob.svg?branch=master)](https://travis-ci.org/opentable/hobknob)\n[\u003cimg src=\"http://standards-badges.herokuapp.com/image?serviceStatusEndpoint=0\u0026logSchema=0\u0026githubReadme=1\"\u003e](http://standards-badges.herokuapp.com/?serviceStatusEndpoint=0\u0026logSchema=0\u0026githubReadme=1)\n[![Join the chat at https://gitter.im/opentable/hobknob](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/opentable/hobknob?utm_source=badge\u0026utm_medium=badge\u0026utm_campaign=pr-badge\u0026utm_content=badge)\n\nHobknob is a feature toggle front-end built on top of [etcd](https://github.com/coreos/etcd).\nIt allows users to create and modify feature toggles, which can then be accesesed in your applications.\n\n### Convention\nFeatures in Hobknob are grouped by application. Each application can have many, uniquely named features. Each feature will either have one on/off toggle or many on/off toggles (see `Categories` below). This gives us a simple way to identify toggles - `ApplicationName/FeatureName[/SecondaryKey]`.\n\n### Categories\nSometimes we need more granularity when toggling features, for example, a feature might be turned on for the .com website but not for the .co.uk website.\n\nHobknob has the concept of feature categories, where you can define secondary keys for each feature. This gives you the ability to set and get toggle values for `App/Feature/SecondaryKey`.\n\nFor the above example, we could define a category called 'Domain Feature Toggles' and set the list of possible key values as `['com', 'couk', 'fr', 'de', ...]`. Then we could set `App/Feature/com` to true and `App/Feature/couk` to false.\n\n### Audit\nAn audit log of all changes is created in etcd and is visible un the UI. When using the authentication mode, usernames will be auditted alongside the changes.\n\n### Etcd\nEtcd is a good fit for feature toggles. It has a good http API to query the state of the toggle, and an eventing system to notify consumers of changes.\nMore information on etcd can be found here: [etcd](https://github.com/coreos/etcd).\n\n## Screenshots\n\n### Application View\n![Application View](screenshots/ApplicationView.png)\n\n### Feature View\n![Feature View](screenshots/FeatureView.png)\n\n### Running the application\n\n## Vagrant\nThe quickest way to run the app locally is to use Vagrant. If you don't have Vagrant you should install it from [here](http://www.vagrantup.com/).\n`vagrant up` will spin up a vagrant instance and install etcd and Hobknob, which are exposed on ports 4001 and 3006 respectfully.\nHobknob itself is deployed in a Docker container inside of the vagrant instance.\n\n### Notes\nThere seems to be an existing issue with Vagrant version 1.7.2 when attempting to install Docker. Currently, Vagrant version 1.7.4 will work.\n\n## Manual\nThe application is dependant on NodeJS version 0.10.26. This can be downloaded [here](http://nodejs.org/download/).\n\n### etcd\nA local (or development) installation of Hobknob is configured to use a locally running etcd instance. A useful guide is available [here](https://github.com/coreos/etcd#building).\nOr, here is a simple way to etcd up and running on a Mac:\n\n```sh\n$ curl -L https://github.com/coreos/etcd/releases/download/v0.4.6/etcd-v0.4.6-darwin-amd64.zip | tar xvz\n$ cd etcd-v0.4.6-darwin-amd64\n$ ./etcd\n```\n\n### Hobknob\n\nThe following will checkout and run Hobknob (accessible http://127.0.0.1:3006/).\n\n```sh\n$ git clone git@github.com:opentable/hobknob.git\n$ cd hobknob\n$ npm install\n$ grunt\n$ npm start\n```\n\n# Preparing the config\n\nTo generate the client-side config, you need to run the following command (until we find a better solution):\n```sh\n$ grunt\n```\n\nYou can then access the site on http://127.0.0.1:3006\n\n## Testing with Protractor\nWe've integrated [protractor](https://github.com/angular/protractor) for end-to-end testing. To start these tests run:\n\n```sh\n# Make sure you have the app running first\n$ npm test\n```\n\n## Configuring Feature Categories\nYou can define the feature categories in the confuration file (config/config.json). Note, category id 0 is reserved for the simple, single value feature toggle category (however, you can still specify it in the config to set the name and description).\n\nExample:\n\n```javascript\n{\n    ...\n\n    \"categories\": [\n        {\n            \"id\": 0, // id = 0 is reserved for the simple feature category only. Name and description are optional\n            \"name\": \"Simple Features\",\n            \"description\": \"Use when you want your feature to be either on or off\"\n        },\n        {\n            \"id\": 1,\n            \"name\": \"Domain Features\",\n            \"description\": \"Use when you want your features to be toggled separately for different domains (e.g. com, couk, fr, ...)\",\n            \"values\": [\"com\", \"couk\", \"de\", \"fr\"] // must define values when id != 0\n        }\n    ]\n}\n```\n\n## Configuring Authentication\nBy default Hobknob ships with authentication disabled. This is configurable by changing the config/config.json config file.\n\n### Turning on Google OAuth\nFirst you must generate a google oauth client Id and client secret. To do this visit the [Google Developer Console](https://console.developers.google.com/project) and create a new project. Select this project once created and go into the section \"APIs and auth\" in the left hand menu. From here you can create a new oath client Id.\n\nTo use oath in Hobknob add the following to your config (config/confg.json).\n\n```\n{\n  \"RequiresAuth\": true,\n  \"AuthProviders\":{\n    \"GoogleAuth\": {\n      \"GoogleClientId\": \"somecientid.apps.googleusercontent.com\",\n      \"GoogleClientSecret\": \"somesecretkey\"\n    }\n  }\n}\n```\n\nThis configuration is shared with Angular so you need to run the following:\n```sh\n$ grunt\n```\n\n#### Extra Authentication params (ie: `hd` param for domain limitation on Google Auth)\n\nYou can add an `authentication` object to the `GoogleAuth` object in your config in order to use extra parameters, like the `hd` Google Auth param. This will limit the valid Google accounts to a specific domain (for Google Apps).\n\n\n```\n{\n  \"RequiresAuth\": true,\n  \"AuthProviders\":{\n    \"GoogleAuth\": {\n      \"GoogleClientId\": \"somecientid.apps.googleusercontent.com\",\n      \"GoogleClientSecret\": \"somesecretkey\",\n      \"authentication\":{  \n        \"hd\":\"example.com\"\n      }\n    }\n  }\n}\n```\n\n\nsee https://developers.google.com/identity/protocols/OpenIDConnect#hd-param\n\n\n### Access Control List\nWhen authentication is enabled, you can control who is allowed to add, update, or delete toggles per application.\n\nThe creator of an application is automatically an owner of that application. Application owners can add other owners via the Owners panel in the Application View.\n\n![Application Owners](screenshots/ApplicationOwners.png)\n\nIf in an emergency, you need to be added to an application's ACL, you can use this command:\n\n```\ncurl -L -X PUT http://\u003cetcd_host\u003e:\u003cetcd_port\u003e/v2/keys/v1/toggleAcl/\u003capplication-name\u003e/\u003cemail\u003e -d value=\u003cemail\u003e\n```\n\n## Configuring Session\nBy default session is stored in-memory using the expressjs connect middleware. For a single machine environment this is fine. When you have multiple load balanced machines you probably want to use some kind of shared stored. Hobknob currently supports [Redis](https://github.com/visionmedia/connect-redis) or [etcd](https://github.com/opentable/connect-etcd) connect middleware.\n\nConfiguring session is simple. Just npm install the module you want to use. For example, to use etcd to store session simple use:\n\n```\nnpm install connect-etcd --save\n```\n\nHobknob will realise the package is installed and assume that you therefore want to use it for session storage.\n\nThe configuration for the session is also stored in the config/config.json file using the following:\n\n```json\n{\n  \"etcdHost\": \"hobknob-etcd.yourenvironment.com\",\n  \"etcdPort\": \"4001\",\n}\n```\n## Configuring Logging\nBy default, express has been configured to use a dev logger to stdout. You can configure to use different logging middleware by supplying configuration in config/config.json file.\n\n```json\n{\n  \"loggingMiddleware\": {\n    \"path\": \"./logging_module\",\n    \"settings\": { }\n  }\n}\n```\n\nNote, the module must be a function with the following standard express middleware signature: `function(settings) { return function(req, res, next) { }; }`\n\n### Example\n\nIn a file called simple-console.js:\n\n```javascript\nmodule.exports = function(settings) {\n  return function(req, res, next) {\n    if (settings.enabled) {\n      console.log('request: ' + req.path);\n    };\n  };\n};\n```\n\nconfig/config.json:\n```json\n{\n  ...\n   \"loggingMiddleware\": {\n     \"path\": \"./simple-console\",\n     \"settings\": {\n       \"enabled\": true\n     }\n   }\n}\n```\n\n## Feature hooks\nYou can add custom hooks that will run for feature-events (add, delete, update), E.g. reporting toggle events to slack, hipchat etc.\n\nThe hooks can implement any or all of the interface methods specified [here](server/exampleHook.js). The function signature is `function(eventInfo, next){}` where `next` is a callback taking one argument (an error).\n\nRegister your hooks by adding them to the `hooks` array in the configuration file:\n\n```\n  \"hooks\": [\n    \"server/exampleHook.js\"\n  ]\n```\n\n## Hobknob Clients\nThere are several clients for different languages.\n\n- https://github.com/opentable/hobknob-client-nodejs\n- https://github.com/opentable/hobknob-client-net\n- https://github.com/opentable/hobknob-client-java\n- https://github.com/opentable/hobknob-client-go\n\n## Release Notes\n\n### 2.0.x Breaking audit trail changes\n\nFeature audits are now stored in the following etcd directory: `http://etcd_host:etcd_port/v2/keys/v1/audit/feature/`.\n\nUse the included script to migrate the audit trail made in versions of Hobknob prior to release 2.0.\n\n```sh\nnode scripts/migrate_etcd_audit_2.0.js \u003cetcd_host\u003e \u003cetcd_port\u003e\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopentable%2Fhobknob","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fopentable%2Fhobknob","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopentable%2Fhobknob/lists"}