{"id":27945155,"url":"https://github.com/metal-stack/api","last_synced_at":"2026-04-01T19:39:51.096Z","repository":{"id":276272093,"uuid":"928310401","full_name":"metal-stack/api","owner":"metal-stack","description":"metal-stack API definition V2","archived":false,"fork":false,"pushed_at":"2026-03-24T15:14:01.000Z","size":2543,"stargazers_count":0,"open_issues_count":7,"forks_count":0,"subscribers_count":5,"default_branch":"main","last_synced_at":"2026-03-25T07:25:45.407Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","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/metal-stack.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":"CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-02-06T12:29:32.000Z","updated_at":"2026-03-24T14:27:58.000Z","dependencies_parsed_at":"2025-03-03T10:26:37.114Z","dependency_job_id":"5485429f-832e-4309-b458-4d123484c2e5","html_url":"https://github.com/metal-stack/api","commit_stats":null,"previous_names":["metal-stack/api"],"tags_count":58,"template":false,"template_full_name":null,"purl":"pkg:github/metal-stack/api","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/metal-stack%2Fapi","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/metal-stack%2Fapi/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/metal-stack%2Fapi/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/metal-stack%2Fapi/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/metal-stack","download_url":"https://codeload.github.com/metal-stack/api/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/metal-stack%2Fapi/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31291174,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-01T13:12:26.723Z","status":"ssl_error","status_checked_at":"2026-04-01T13:12:25.102Z","response_time":53,"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":[],"created_at":"2025-05-07T12:56:12.550Z","updated_at":"2026-04-01T19:39:50.955Z","avatar_url":"https://github.com/metal-stack.png","language":"TypeScript","readme":"# metal-stack.io api\n\n[![Release](https://github.com/metal-stack/api/actions/workflows/main.yml/badge.svg)](https://github.com/metal-stack/api/actions/workflows/main.yml) [![go.dev reference](https://img.shields.io/badge/go.dev-reference-007d9c?logo=go\u0026logoColor=white\u0026style=flat-square)](https://pkg.go.dev/github.com/metal-stack/api) ![GitHub go.mod Go version](https://img.shields.io/github/go-mod/go-version/metal-stack/api) ![GitHub release (latest SemVer)](https://img.shields.io/github/v/release/metal-stack/api) [![Go Report Card](https://goreportcard.com/badge/github.com/metal-stack/api)](https://goreportcard.com/report/github.com/metal-stack/api)\n\n\u003e [!IMPORTANT]\n\u003e Please note that this repository is still in alpha stage. For now, the primary API is still defined in the [metal-api](https://github.com/metal-stack/metal-api) project. We will make a special announcement when this repository becomes GA.\n\nThis is the V2 API of [metal-stack.io](https://metal-stack.io) to implement [MEP-4](https://metal-stack.io/docs/MEP-4-multi-tenancy-for-the-metal-api).\n\n## Usage examples\n\nCan be found in the [examples](examples/) folder.\n\n## Conventions\n\nMethod options provide an intuitve and declarative way of providing annotations to service methods.\nThese are used for scoping api-methods, which are getting utilized for authentication, authorization and auditing (mainly in interceptors).\n\n### Motivational Example\n\n```proto\nservice IPService {\n  // Get an ip\n  rpc Get(IPServiceGetRequest) returns (IPServiceGetResponse) {\n    option (project_roles) = PROJECT_ROLE_OWNER;\n    option (project_roles) = PROJECT_ROLE_EDITOR;\n    option (project_roles) = PROJECT_ROLE_VIEWER;\n    option (auditing) = AUDITING_EXCLUDED;\n  }\n  // Create an ip\n  rpc Create(IPServiceCreateRequest) returns (IPServiceCreateResponse) {\n    option (project_roles) = PROJECT_ROLE_OWNER;\n    option (project_roles) = PROJECT_ROLE_EDITOR;\n  }\n}\n\n// IPServiceCreateRequest is the request payload for a ip create request\nmessage IPServiceCreateRequest {\n  // Network from which the IP should be created\n  string network = 1 [(buf.validate.field).string = {\n    min_len: 2\n    max_len: 128\n  }];\n  // Project of the ip\n  string project = 2 [(buf.validate.field).string.uuid = true];\n  // Name of the ip\n  optional string name = 3 [(buf.validate.field).string.(metalstack.api.v2.is_name) = true];\n  // Description of the ip\n  optional string description = 4 [(buf.validate.field).string.(metalstack.api.v2.is_description) = true];\n  // IP if given try to create this ip if still available\n  optional string ip = 5 [(buf.validate.field).string.ip = true];\n  // Machine for which this ip should get created\n  optional string machine = 6 [(buf.validate.field).string.uuid = true];\n  // Labels to put onto the ip\n  optional Labels labels = 7;\n  // Type of the IP, ether ephemeral (default), or static\n  optional IPType type = 8 [(buf.validate.field).enum.defined_only = true];\n  // Addressfamily of the IP to create, defaults to ipv4\n  optional IPAddressFamily address_family = 9 [(buf.validate.field).enum.defined_only = true];\n}\n```\n\nIn this example we can see the motivation behind the method options.\n\n1. Get: can be issued by project owner, editor, viewer and is excluded from auditing\n2. Allocate: can be used by project owner, editor\n3. Both methods are project-scoped, since they are annotated by a project role -\u003e Request object needs to have the **project** field in order to specify the target project of the service method\n\nFurther explanations are explained in the following.\n\n### Auth\n\nThese options specify the RBAC of the api-endpoint.\n\n| Option         | Description                                  | Values      | Explanation                                            |\n| -------------- | -------------------------------------------- | ----------- | ------------------------------------------------------ |\n| TENANT_ROLE\\_  | Specifies the required tenant role           | UNSPECIFIED |                                                        |\n|                |                                              | OWNER       | tenant owner                                           |\n|                |                                              | EDITOR      | tenant editor                                          |\n|                |                                              | VIEWER      | tenant viewer                                          |\n|                |                                              | GUEST       | tenant guest                                           |\n| PROJECT_ROLE\\_ | Specifies the required project role          | UNSPECIFIED |                                                        |\n|                |                                              | OWNER       | project owner                                          |\n|                |                                              | EDITOR      | project editor                                         |\n|                |                                              | VIEWER      | project viewer                                         |\n| ADMIN_ROLE\\_   | Specifies the required admin role            | UNSPECIFIED |                                                        |\n|                |                                              | EDITOR      | admin editor                                           |\n|                |                                              | VIEWER      | admin viewer                                           |\n| VISIBILITY\\_   | Specifies the visibility of the api-endpoint | UNSPECIFIED |                                                        |\n|                |                                              | PUBLIC      | api-method is visible to public, a token is not needed |\n|                |                                              | SELF        | api-method is scoped to owner resources                |\n\n\u003e [!IMPORTANT]\n\u003e\n\u003e Every operation needs at least an option, which references the scope of the request: **ROLE** or **VISIBILITY**\n\n\u003e [!CAUTION]\n\u003e\n\u003e If we use a Tenant or Project role, the request will be respectively scoped as Tenant or Project request.\n\u003e Tenant-Requests must have the field **login**, which is the tenant id and specifies the tenant on which the service-method is scoped.\n\u003e Project-Requests must have the field **project**, which is the project id and specifies the project on which the service-method is scoped.\n\n### Auditing\n\nFor traceability we require to store audit-logs.\n\n| Option     | Description                              | Values      | Explanation              |\n| ---------- | ---------------------------------------- | ----------- | ------------------------ |\n| AUDITING\\_ | Specifies if the api-endpoint is audited | UNSPECIFIED | DEFAULT: included        |\n|            |                                          | INCLUDED    | operation is audited     |\n|            |                                          | EXCLUDED    | operation is not audited |\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmetal-stack%2Fapi","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmetal-stack%2Fapi","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmetal-stack%2Fapi/lists"}