{"id":22004701,"url":"https://github.com/davidcoles/gpn","last_synced_at":"2026-05-04T06:39:17.076Z","repository":{"id":160352634,"uuid":"635237187","full_name":"davidcoles/gpn","owner":"davidcoles","description":"'guard Private Network","archived":false,"fork":false,"pushed_at":"2024-12-13T15:33:05.000Z","size":132,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-01-28T12:46:45.388Z","etag":null,"topics":["mtls","oauth2","oidc","sso","vpn","wireguard"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/davidcoles.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}},"created_at":"2023-05-02T09:06:33.000Z","updated_at":"2024-12-13T15:31:02.000Z","dependencies_parsed_at":"2023-10-25T10:36:25.879Z","dependency_job_id":null,"html_url":"https://github.com/davidcoles/gpn","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/davidcoles%2Fgpn","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/davidcoles%2Fgpn/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/davidcoles%2Fgpn/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/davidcoles%2Fgpn/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/davidcoles","download_url":"https://codeload.github.com/davidcoles/gpn/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245063125,"owners_count":20554868,"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":["mtls","oauth2","oidc","sso","vpn","wireguard"],"created_at":"2024-11-30T00:16:49.983Z","updated_at":"2026-05-04T06:39:12.054Z","avatar_url":"https://github.com/davidcoles.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# gpn - 'guard Private Network\n\n(More [documentation ...](docs/))\n\n## Introduction\n\nA daemon to manage WireGuard keys, firewall rules and routing table.\n\nWireGuard peers are given an x509 certificate from a certification\nagency of your choice which allows them access an HTTPS endpoint with\nmTLS. From there the user can authenticate via an OIDC provider\n(tested with Microsoft Azure AD and Keycloak) and, dependent on the\nclaims returned in the access token, the device is added to the\nappropriate firewall rules via ipset(8).\n\nIf the token can not be refreshed (eg. because the user has been\ndisabled) then the firewall rules are withdrawn. If the claims in the\nuser's token have changed then these will cause the firewall to be\nupdated appropriately. OCSP support is yet to be added, but that could\nalso lead to access being withdrawn if a certificate is revoked.\n\nMultiple instances can be run as a cluster (currently using Corosync)\nand placed behind a load balancer to create a redunant service - use\nBIRD or Quagga to advertise each peer's /32 address (or an aggregate\nprefix) into your organisation's routing table.\n\nCorosync currently needs to be installed and running - there's no need\nto have multiple instances, but being able to contact the local\ncorosync closed process group daemon is a requirement. This will\nrequirement will be removed soon as the code evolves.\n\nWhilst the standard WireGuard client can be used to access the VPN, it\nwould be nice to have a tailored client which can query the\n/api/... endpoints that the daemon provides. This could be used for\nautomatic configuration of the VPN client, notification to the user of\nOIDC authentication state, etc.\n\nA truly awful proof-of-concept for macOS can be found in the\n[gpnc/](gpnc/) directory.\n\nCurrently the devices database is stored as a YAML file and converted\nto JSON, but this could be generated from a database, stored in LDAP,\netc.  Devices can be added, removed, keys chenged, etc., by\nregenerating the JSON file, deploying to instances if necessary, and\nsending a SIGQUIT to daemon (this should probably be changed to SIGUSR2).\n\nYou will need to create your own firewall rules - the daemon will just\nupdate ipsets which you should define and incorporate into your\nruleset.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdavidcoles%2Fgpn","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdavidcoles%2Fgpn","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdavidcoles%2Fgpn/lists"}