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`.