github.com/gemaraproj/gemara@v1.3.0

docs/sdk/go-sdk.md raw

  1---
  2layout: page
  3title: Go SDK
  4---
  5
  6The Go SDK provides type-safe APIs for reading, writing, converting, and bundling Gemara documents. Types are generated from CUE schemas using [cuegen](https://github.com/gemaraproj/cuegen).
  7
  8**[Go Package Reference →](https://pkg.go.dev/github.com/gemaraproj/go-gemara)**
  9
 10## Installation
 11
 12```bash
 13go get github.com/gemaraproj/go-gemara
 14```
 15
 16## Loading Documents
 17
 18`gemara.Load` is a generic loader — substitute the type parameter for any document kind (`gemara.GuidanceCatalog`, `gemara.ControlCatalog`, `gemara.Policy`, `gemara.EvaluationLog`, etc.). Format (YAML or JSON) is detected from the file extension.
 19
 20```go
 21package main
 22
 23import (
 24    "context"
 25    "fmt"
 26    "log"
 27
 28    "github.com/gemaraproj/go-gemara"
 29    "github.com/gemaraproj/go-gemara/fetcher"
 30)
 31
 32func main() {
 33    f := &fetcher.File{}
 34    ctx := context.Background()
 35
 36    catalog, err := gemara.Load[gemara.ControlCatalog](ctx, f, "path/to/controls.yaml")
 37    if err != nil {
 38        log.Fatal(err)
 39    }
 40
 41    for _, control := range catalog.Controls {
 42        fmt.Printf("Control: %s - %s\n", control.Id, control.Title)
 43    }
 44}
 45```
 46
 47The `fetcher` package provides three implementations of the `gemara.Fetcher` interface:
 48
 49- `fetcher.File` — reads from the local filesystem
 50- `fetcher.HTTP` — fetches over HTTP(S)
 51- `fetcher.URI` — dispatches by scheme (`file://`, `http(s)://`, or bare paths)
 52
 53`ControlCatalog` and `GuidanceCatalog` also expose `LoadFiles` for merging multiple sources, and `ControlCatalog.LoadNestedCatalog` for YAML files where the catalog is wrapped in a single key (e.g. `catalog:`).
 54
 55## Converting to OSCAL
 56
 57```go
 58import (
 59    "github.com/gemaraproj/go-gemara"
 60    "github.com/gemaraproj/go-gemara/fetcher"
 61    "github.com/gemaraproj/go-gemara/gemaraconv"
 62)
 63
 64f := &fetcher.File{}
 65ctx := context.Background()
 66
 67catalog, _ := gemara.Load[gemara.ControlCatalog](ctx, f, "path/to/catalog.yaml")
 68oscalCatalog, _ := gemaraconv.ControlCatalog(catalog).ToOSCAL()
 69
 70guidance, _ := gemara.Load[gemara.GuidanceCatalog](ctx, f, "path/to/guidance.yaml")
 71oscalCat, oscalProfile, _ := gemaraconv.GuidanceCatalog(guidance).ToOSCAL("relative/path/to/catalog.json")
 72```
 73
 74A `ControlCatalog` can also be rendered to Markdown via `gemaraconv.ControlCatalog(catalog).ToMarkdown(ctx)`.
 75
 76## Converting to SARIF
 77
 78`EvaluationLog` results can be emitted as SARIF for surfacing in code-scanning tools. A `ControlCatalog` is required to resolve control metadata referenced from the log.
 79
 80```go
 81catalog, _ := gemara.Load[gemara.ControlCatalog](ctx, f, "path/to/catalog.yaml")
 82
 83evaluationLog := &gemara.EvaluationLog{ /* populate */ }
 84sarifBytes, _ := gemaraconv.EvaluationLog(evaluationLog).ToSARIF("path/to/artifact.md", catalog)
 85```
 86
 87## Bundling and Distributing via OCI
 88
 89The `bundle` package assembles the full dependency tree (`extends` + `imports`) of a Gemara document, packs it into an OCI layout, and pushes it to a registry.
 90
 91```go
 92import (
 93    "github.com/gemaraproj/go-gemara/bundle"
 94    "github.com/gemaraproj/go-gemara/fetcher"
 95    "oras.land/oras-go/v2"
 96    "oras.land/oras-go/v2/content/oci"
 97    "oras.land/oras-go/v2/registry/remote"
 98)
 99
100data, _ := os.ReadFile("policy.yaml")
101src := bundle.File{Name: "policy.yaml", Data: data}
102
103m := bundle.Manifest{BundleVersion: "1", GemaraVersion: "v1.0.0"}
104asm := bundle.NewAssembler(&fetcher.URI{})
105b, _ := asm.Assemble(ctx, m, src)
106
107layoutStore, _ := oci.New("./bundle-output")
108desc, _ := bundle.Pack(ctx, layoutStore, b)
109_ = layoutStore.Tag(ctx, desc, "v1.0.0")
110
111repo, _ := remote.NewRepository("registry.example.com/org/bundle")
112tagDesc, _ := layoutStore.Resolve(ctx, "v1.0.0")
113_ = oras.CopyGraph(ctx, layoutStore, repo, tagDesc, oras.DefaultCopyGraphOptions)
114_ = repo.Tag(ctx, tagDesc, "v1.0.0")
115
116unpacked, _ := bundle.Unpack(ctx, repo, "v1.0.0")
117_ = unpacked
118```
119
120## Developer Tooling
121
122The SDK repository also includes two binaries — `oscalexport` and `typestagger` — that exist as test and development infrastructure for SDK maintainers, not as supported end-user CLIs. `oscalexport` is used to regenerate OSCAL fixtures from the bundled test catalogs (`make oscal-export`), and `typestagger` post-processes generated Go types after `make generate`. See the [`go-gemara` repository](https://github.com/gemaraproj/go-gemara) for usage in a development workflow.
123
124## Relationship to Other Components
125
126### [The Model](../model)
127Provides the conceptual foundation. Go SDK types correspond to elements in the model.
128
129### [The Schemas](../schema/)
130Go SDK types are generated from the CUE schemas, ensuring consistency between validation and programmatic access. The schema version supported by a given SDK release is exposed as `gemara.SchemaVersion`.