{"id":18806412,"url":"https://github.com/ansiwen/unitang","last_synced_at":"2026-01-08T15:30:15.530Z","repository":{"id":95640576,"uuid":"150312218","full_name":"ansiwen/unitang","owner":"ansiwen","description":"MirageOS (Ocaml Unikernel) implementation of a tang server","archived":false,"fork":false,"pushed_at":"2018-10-09T00:50:45.000Z","size":37,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":4,"default_branch":"master","last_synced_at":"2024-12-29T21:25:08.219Z","etag":null,"topics":["clevis","latchset","mirageos","ocaml","tang","unikernel"],"latest_commit_sha":null,"homepage":"","language":"OCaml","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ansiwen.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}},"created_at":"2018-09-25T18:35:35.000Z","updated_at":"2023-02-04T19:53:40.000Z","dependencies_parsed_at":"2023-05-06T03:04:38.028Z","dependency_job_id":null,"html_url":"https://github.com/ansiwen/unitang","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ansiwen%2Funitang","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ansiwen%2Funitang/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ansiwen%2Funitang/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ansiwen%2Funitang/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ansiwen","download_url":"https://codeload.github.com/ansiwen/unitang/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":239742416,"owners_count":19689309,"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":["clevis","latchset","mirageos","ocaml","tang","unikernel"],"created_at":"2024-11-07T22:48:30.804Z","updated_at":"2026-01-08T15:30:15.478Z","avatar_url":"https://github.com/ansiwen.png","language":"OCaml","funding_links":[],"categories":[],"sub_categories":[],"readme":"# UniTang\n\nThis is the implementation of a [tang](https://github.com/latchset/tang)\nserver as a unikernel, based on [MirageOS](https://mirage.io/), a unikernel\nframework entirely written in the statically typed functional language\n[OCaml](https://ocaml.org/).\n\nIt's still in an early state and only supports one server key at the moment.\n\n## Building\n\nYou have to have the ocaml package manager [opam](https://opam.ocaml.org/)\ninstalled. Then for example:\n\n```\n$ opam install mirage\n$ mirage configure -t unix --net socket\n$ make depend\n$ make\n$ ./unitang --help\n\nunitang(1)                      Unitang Manual                      unitang(1)\n\n\n\nNAME\n       unitang\n\nSYNOPSIS\n       unitang [OPTION]...\n\nUNIKERNEL PARAMETERS\n       --ips=IPS (absent=0.0.0.0)\n           The IPv4 addresses bound by the socket in the unikernel.\n\n       -l LEVEL, --logs=LEVEL (absent MIRAGE_LOGS env)\n           Be more or less verbose. LEVEL must be of the form *:info,foo:debug\n           means that that the log threshold is set to info for every log\n           sources but the foo which is set to debug.\n\n       --socket=SOCKET\n           The IPv4 address bound by the socket in the unikernel.\n\nAPPLICATION OPTIONS\n       --adv=VAL (required)\n           The advertised jws containing the public key of the deriving key.\n           This key is required.\n\n       --dkey=VAL (required)\n           The jwk of the deriving key. This key is required.\n\n       --port=VAL (absent=8080)\n           Listening HTTP port.\n\nOPTIONS\n       --help[=FMT] (default=auto)\n           Show this help in format FMT. The value FMT must be one of `auto',\n           `pager', `groff' or `plain'. With `auto', the format is `pager` or\n           `plain' whenever the TERM env var is `dumb' or undefined.\n\nENVIRONMENT\n       These environment variables affect the execution of unitang:\n\n       MIRAGE_LOGS\n           See option --logs.\n\n\n\nUnitang                                                             unitang(1)\n\n$ MIRAGE_LOGS=debug ./unitang --adv $(cat db/adv.jws) --dkey $(cat db/EIO0CuWE-3AeBlnkqmsr8flT_ks.jwk)\n2018-10-04 18:21:34 +02:00: INF [tcpip-stack-socket] Manager: connect\n2018-10-04 18:21:34 +02:00: INF [tcpip-stack-socket] Manager: configuring\n2018-10-04 18:21:34 +02:00: INF [http] listening on 8080/TCP\n...\n```\nFor how to create the JWS and JWK files, refer to the\n[tang](https://github.com/latchset/tang) documentation.\n\n\nIn another shell:\n```\n$ echo UniTangRulez | clevis encrypt tang '{\"url\": \"http://localhost:8080\"}' \u003e secret.jwe\nThe advertisement contains the following signing keys:\n\nqhjjYdwJOoXdBa0JMXJJxCU_ZMw\n\nDo you wish to trust these keys? [ynYN] y\n$ clevis decrypt \u003c secret.jwe \nUniTangRulez\n$\n```\n\nAccording output of unitang:\n```\n$ MIRAGE_LOGS=debug ./unitang --adv $(cat db/adv.jws) --dkey $(cat db/EIO0CuWE-3AeBlnkqmsr8flT_ks.jwk)\n2018-10-04 18:30:18 +02:00: INF [tcpip-stack-socket] Manager: connect\n2018-10-04 18:30:18 +02:00: INF [tcpip-stack-socket] Manager: configuring\n2018-10-04 18:30:18 +02:00: INF [http] listening on 8080/TCP\n2018-10-04 18:30:57 +02:00: INF [http] [1] serving //localhost:8080/adv/.\n2018-10-04 18:30:57 +02:00: DBG [api] Request header:\naccept: */*\nhost: localhost:8080\nuser-agent: curl/7.59.0\n\n\n2018-10-04 18:30:57 +02:00: INF [api] 200 - GET /adv/\n2018-10-04 18:30:57 +02:00: DBG [api] Webmachine path: v3b13, v3b12, v3b11, v3b10, v3b9, v3b8, v3b7, v3b6, v3b5, v3b4, v3b3, v3c3, v3c4, v3d4, v3e5, v3f6, v3g7, v3g8, v3h10, v3i12, v3l13, v3m16, v3n16, v3o16, v3o18\n2018-10-04 18:30:57 +02:00: DBG [api] Response header:\naccess-control-allow-headers: Accept, Content-Type, Authorization\naccess-control-allow-methods: GET, HEAD, POST, DELETE, OPTIONS, PUT, PATCH\naccess-control-allow-origin: *\ncontent-type: application/jose+json\nvary: Accept, Accept-Encoding, Accept-Charset, Accept-Language\n\n\n2018-10-04 18:30:57 +02:00: DBG [api] Response body:\n{\"payload\":\"eyJrZXlzIjpbeyJhbGciOiJFQ01SIiwiY3J2IjoiUC01MjEiLCJrZXlfb3BzIjpbImRlcml2ZUtleSJdLCJrdHkiOiJFQyIsIngiOiJBQ0FjMlJET0pBZVpXYUJfZWZKMFhhUVhrdmlWVWl3Yk5DZlVnUklhdnFBb1FMRzlLQ3pTNzBaVVdnOWlJM3UyMThTcUJadkY3cXc5eThpR0RqOUVGUS1iIiwieSI6IkFOMFRqZ1kyQ3Judmo5eHhfUHotUXpkOVJZUnJ5RlRkVDJpbS1pdGJtdlhmRENsRTU4M2tyNjNRamdMVmZNQ1lONXQwVHd0YWFNSVNCd1JqOFRXOWpWN3MifSx7ImFsZyI6IkVTNTEyIiwiY3J2IjoiUC01MjEiLCJrZXlfb3BzIjpbInZlcmlmeSJdLCJrdHkiOiJFQyIsIngiOiJBTHVqRnUzRFpJQUFqVGl5cnE2N0ctSEZ6T3BvQU5RSHVYaHBYR0VHQUs4aWJldy1wOUFwOHhpWjlwTEVPRVRIenFYOWpQRFlPOWtxRW5nbHl2X3FpZVpaIiwieSI6IkFLTC1oN2p4Q3dzNmJLdE9TNHI1MmRwRUkxVTJHOThHTThyLU4zNC0zRldNd0FRdGlBdXR1NTBiYjRJNUphSU9QUkkzSnllcUpFbXk4ajcwdk52QTA3TVAifV19\",\"protected\":\"eyJhbGciOiJFUzUxMiIsImN0eSI6Imp3ay1zZXQranNvbiJ9\",\"signature\":\"AMZUI3l-A6pbGAIMlQ9KQmF3Qy_VsDzE_UW2fZnxl34S6Hril3SkcG5RBdFktmfx9FiOtiR6hmLb6w3LRDJMShzkAFRrBKlGtifKP6R8dbh-MlXkn3vKy1gNwspBYo9ErEClvwmSZ80Bq99whjPOsdI_DODh54Ct5II1L9pmuxUrVtLV\"}\n2018-10-04 18:30:57 +02:00: INF [http] [1] closing\n2018-10-04 18:32:17 +02:00: INF [http] [2] serving //localhost:8080/rec/EIO0CuWE-3AeBlnkqmsr8flT_ks.\n2018-10-04 18:32:17 +02:00: DBG [api] Request header:\naccept: */*\ncontent-length: 230\ncontent-type: application/jwk+json\nhost: localhost:8080\nuser-agent: curl/7.59.0\n\n\n2018-10-04 18:32:17 +02:00: DBG [api] Request body:\n{\"alg\":\"ECMR\",\"crv\":\"P-521\",\"kty\":\"EC\",\"x\":\"AZvSWTtsxIVRQAYoURTVMAOUDXzdPYkrNI4X69ET2n9bXFhtga_JHNY3KOuH9lvqNSaJ7NTkXgJZZATC4_qXMCJQ\",\"y\":\"ARiaxRnfhX0HuBrwd31yQX2Me9ANxeZ-1rTc-DRYSWCVVp-rFLF8TV_VwRi4oFWM6ljR4mFAYZvllH9Q_sEtGKMO\"}\n\n2018-10-04 18:32:17 +02:00: INF [api] 200 - POST /rec/EIO0CuWE-3AeBlnkqmsr8flT_ks\n2018-10-04 18:32:17 +02:00: DBG [api] Webmachine path: v3b13, v3b12, v3b11, v3b10, v3b9, v3b8, v3b7, v3b6, v3b5, v3b4, v3b3, v3c3, v3c4, v3d4, v3e5, v3f6, v3g7, v3g8, v3h10, v3i12, v3l13, v3m16, v3n16, v3n11, v3p11, v3o20, v3o18\n2018-10-04 18:32:17 +02:00: DBG [api] Response header:\naccess-control-allow-headers: Accept, Content-Type, Authorization\naccess-control-allow-methods: GET, HEAD, POST, DELETE, OPTIONS, PUT, PATCH\naccess-control-allow-origin: *\ncontent-type: application/jwk+json\nvary: Accept, Accept-Encoding, Accept-Charset, Accept-Language\n\n\n2018-10-04 18:32:17 +02:00: DBG [api] Response body:\n{\"alg\":\"ECMR\",\"crv\":\"P-521\",\"key_ops\":[\"deriveKey\"],\"kty\":\"EC\",\"x\":\"AWo5ZMji0DtEBolLXQYzHBPCX99UBsIkOzt7TNTczaUzsQd8CrdKI0UMSh0NxqTWq5_trq-mKRVBh_ejpsk8ZZ5R\",\"y\":\"AU9ltb9k_YsOOCFw-bR40yRIkU5wRMF7EPHAmnPGIQK6LWiiQqlVO4gE0jlYTCGAnkzrawnSj6INEBqkptvjdvfL\"}\n2018-10-04 18:32:17 +02:00: INF [http] [2] closing\n...\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fansiwen%2Funitang","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fansiwen%2Funitang","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fansiwen%2Funitang/lists"}