{"id":18320214,"url":"https://github.com/gedex/cas","last_synced_at":"2025-07-28T16:04:31.981Z","repository":{"id":57605658,"uuid":"172458388","full_name":"gedex/cas","owner":"gedex","description":"Command as a Service.","archived":false,"fork":false,"pushed_at":"2019-02-25T08:18:26.000Z","size":7,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-09T14:26:09.824Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/gedex.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}},"created_at":"2019-02-25T07:45:00.000Z","updated_at":"2020-07-16T07:00:18.000Z","dependencies_parsed_at":"2022-09-26T20:01:51.808Z","dependency_job_id":null,"html_url":"https://github.com/gedex/cas","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/gedex/cas","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gedex%2Fcas","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gedex%2Fcas/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gedex%2Fcas/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gedex%2Fcas/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gedex","download_url":"https://codeload.github.com/gedex/cas/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gedex%2Fcas/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":267543261,"owners_count":24104536,"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-28T02:00:09.689Z","response_time":68,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","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-11-05T18:15:34.432Z","updated_at":"2025-07-28T16:04:31.938Z","avatar_url":"https://github.com/gedex.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"cas\n===\n\n\u003e Command as a Service.\n\nAllows you to execute commands in your server via HTTP. Commands to execute are defined in YAML config file.\n\n[![Build][travis-image]][travis-url]\n\n## Usage\n\nGiven `config.yml`:\n\n```yaml\n/hello_world:\n    command: echo\n    args:\n        - hello world\n/ping/google:\n    command: ping\n    args:\n        - -c\n        - 1\n        - google.com\n```\n\nstart `cas` with:\n\n```\ncas -c config.yml\n```\n\nDefined commands can be requested via POST:\n\n```\ncurl -X POST 'http://localhost:1307/hello_world'\n\nHTTP/1/1 200 OK\n{\n  \"request_id\": \"bhpfi1krtr32369i8keg\",\n  \"output\": \"hello world\\n\",\n  \"error\": \"\",\n  \"status\": 200\n}\n\ncurl -X POST 'http://localhost:1307/ping/google'\n\nHTTP/1/1 200 OK\n{\n  \"request_id\": \"bhpfifkrtr32369i8kfg\",\n  \"output\": \"PING google.com (216.239.38.120): 56 data bytes\\n64 bytes from 216.239.38.120: icmp_seq=0 ttl=52 time=29.604 ms\\n\\n--- google.com ping statistics ---\\n1 packets transmitted, 1 packets received, 0.0% packet loss\\nround-trip min/avg/max/stddev = 29.604/29.604/29.604/0.000 ms\\n\",\n  \"error\": \"\",\n  \"status\": 200\n}\n```\n\nSuccessful request always responded with 200 OK, even if command exited with\nnon-zero.\n\n### Passing args\n\n**config.yml:**\n\n```yaml\n/hello:\n    command: echo\n    args:\n        - hello\n    allow:\n        - args\n```\n\n**example request:**\n\n```\ncurl -X POST 'http://localhost:1307/hello' \\\n    -H 'Content-Type: application/json' \\\n    -d '{\"args\": [\"world\", \"my dear\"]}'\n\nHTTP/1/1 200 OK\n{\n  \"request_id\": \"bhpfjokrtr323oi3qqm0\",\n  \"output\": \"hello world my dear\\n\",\n  \"error\": \"\",\n  \"status\": 200\n}\n```\n\nIf `args` is not in `allow` list, then http 403 is returned:\n\n```\nHTTP/1.1 403 Forbidden\n{\n  \"request_id\": \"bhpfkocrtr32413hipt0\",\n  \"output\": \"\",\n  \"error\": \"args param is not allowed\",\n  \"status\": 403\n}\n```\n\n### Passing envs\n\n**config.yml:**\n\n```yaml\n/env:\n    command: env\n    envs:\n        - FOO=BAR\n        - BAR=BAZ\n    allow:\n        - envs\n```\n\n**example request:**\n\n```\ncurl -X POST 'http://localhost:1307/env' \\\n    -H 'Content-Type: application/json' \\\n    -d '{\"envs\": [\"SOMETHING=ELSE\"]}'\n\nHTTP/1/1 200 OK\n{\n  \"request_id\": \"bhpfmfcrtr324eph7e40\",\n  \"output\": \"FOO=BAR\\nBAR=BAZ\\nSOMETHING=ELSE\\n\",\n  \"error\": \"\",\n  \"status\": 200\n}\n```\n\nIf `envs` is not in `allow` list, then http 403 is returned:\n\n```\nHTTP/1.1 403 Forbidden\n{\n  \"request_id\": \"bhpfonkrtr324l2p6pgg\",\n  \"output\": \"\",\n  \"error\": \"envs param is not allowed\",\n  \"status\": 403\n}\n```\n\n### Passing stdin\n\n**./file.txt:**\n\n```\nhello\nthere\n```\n\n**config.yml:**\n\n```yaml\n/diff:\n   command: diff\n   args:\n       - file.txt\n       - '-'\n   dir: ./ \n   allow:\n       - stdin\n```\n\n**example request:**\n\n```\ncurl -X POST 'http://localhost:1307/diff' \\\n    -H 'Content-Type: application/json' \\\n    -d '{\"stdin\": \"hello\"}'\n\nHTTP/1/1 200 OK\n{\n  \"request_id\": \"bhpfso4rtr324ri6polg\",\n  \"output\": \"1,2c1\\n\u003c hello\\n\u003c there\\n---\\n\u003e hello\\n\\\\ No newline at end of file\\n\",\n  \"error\": \"exit status 1\",\n  \"status\": 200\n}\n```\n\nIf `stdin` is not in `allow` list, then http 403 is returned:\n\n```\nHTTP/1.1 403 Bad Request\n{\n  \"request_id\": \"bhpftgcrtr3254845s9g\",\n  \"output\": \"\",\n  \"error\": \"stdin param is not allowed\",\n  \"status\": 403\n}\n```\n\n### Callback / Webhook\n\n**config.yml:**\n\n```yaml\n/ping:\n    command: ping\n    args:\n        - -c\n        - 3\n        - -i\n        - 2\n        - gogle.com\n    allow:\n        - callback\n\n```\n\n**example request:**\n\n```\ncurl -X POST 'http://localhost:1307/ping' \\\n    -H 'Content-Type: application/json' \\\n    -d '{\"callback\": \"https://postb.in/DPb3wkdG\"}'\n{\n  \"request_id\": \"bhpfso4rtr324ri6polg\",\n  \"url\": \"https://postb.in/DPb3wkdG\",\n}\n```\n\n`cas` will post the result to https://postb.in/DPb3wkdG:\n\n```\n{\n  \"request_id\": \"bhpfso4rtr324ri6polg\",\n  \"output\": \"PING gogle.com (172.217.194.103): 56 data bytes\\n64 bytes from 172.217.194.103: icmp_seq=0 ttl=42 time=29.158 ms\\n64 bytes from 172.217.194.103: icmp_seq=1 ttl=42 time=24.744 ms\\n64 bytes from 172.217.194.103: icmp_seq=2 ttl=42 time=25.163 ms\\n\\n--- gogle.com ping statistics ---\\n3 packets transmitted, 3 packets received, 0.0% packet loss\\nround-trip min/avg/max/stddev = 24.744/26.355/29.158/1.989 ms\\n\",\n  \"error\": \"\",\n  \"status\": 200\n}\n\n```\n\n[travis-image]: https://img.shields.io/travis/gedex/cas/master.svg?label=linux\n[travis-url]: https://travis-ci.org/gedex/cas\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgedex%2Fcas","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgedex%2Fcas","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgedex%2Fcas/lists"}