### Install Source: https://github.com/hstern/go-rar/blob/main/README.md Install the go-rar library using go get. ```sh go get github.com/hstern/go-rar@latest ``` -------------------------------- ### Quickstart Source: https://github.com/hstern/go-rar/blob/main/README.md Parse, validate, and use authorization details. ```go package main import ( "fmt" "log" "github.com/hstern/go-rar" ) func main() { const payload = `[{"type":"common","actions":["read","write"],"locations":["https://api.example.com/v1/data"]}]` details, err := rar.ParseArray([]byte(payload)) if err != nil { log.Fatal(err) } if err := rar.ValidateAll(details); err != nil { log.Fatal(err) } fmt.Printf("parsed %d authorization detail(s); first type = %q\n", len(details), details[0].Type()) } ``` -------------------------------- ### SPDX License Identifier Source: https://github.com/hstern/go-rar/blob/main/README.md Example of the SPDX License Identifier in source files. ```go // Copyright 2026 The go-rar Authors // SPDX-License-Identifier: Apache-2.0 ``` -------------------------------- ### Per-file SPDX header example Source: https://github.com/hstern/go-rar/blob/main/AGENTS.md The required two-line header for every .go file, including tests, before the package declaration. ```go // Copyright 2026 The go-rar Authors // SPDX-License-Identifier: Apache-2.0 package rar ``` -------------------------------- ### Quick checks before pushing Source: https://github.com/hstern/go-rar/blob/main/AGENTS.md Commands to run locally to ensure code quality and correctness before pushing changes. These checks are also performed in CI. ```shell gofmt -l . # must be empty go vet ./... go mod tidy -diff # no drift go test -race -shuffle=on ./... golangci-lint run ./... ``` -------------------------------- ### Authorization request — EncodeForm Source: https://github.com/hstern/go-rar/blob/main/README.md Composing a CommonType and encoding it for an authorization request. ```go c := &rar.CommonType{TypeName: "common"} c.Actions = []string{"read"} c.Locations = []string{"https://api.example.com/v1/data"} details := rar.AuthorizationDetails{c} value, err := rar.EncodeForm(details) if err != nil { log.Fatal(err) } v := url.Values{} v.Set("authorization_details", value) v.Set("response_type", "code") v.Set("client_id", "client123") // Wire into the redirect URL: https://as.example.com/authorize? ``` -------------------------------- ### Token response — ParseArray from a JSON body Source: https://github.com/hstern/go-rar/blob/main/README.md Decoding authorization details from a token response JSON body. ```go var resp struct { AccessToken string `json:"access_token"` TokenType string `json:"token_type"` ExpiresIn int `json:"expires_in"` AuthorizationDetails json.RawMessage `json:"authorization_details"` } if err := json.NewDecoder(httpResp.Body).Decode(&resp); err != nil { log.Fatal(err) } details, err := rar.ParseArray(resp.AuthorizationDetails) if err != nil { log.Fatal(err) } _ = details ``` -------------------------------- ### multiple.json — RFC 9396 §4 Source: https://github.com/hstern/go-rar/blob/main/internal/specfixtures/README.md A two-element array. The second element carries type-specific members (instructedAmount, creditorName, creditorAccount, remittanceInformationUnstructured) alongside the common members, exercising the open-extension path. ```json [ { "type": "account_information", "actions": ["list_accounts", "read_balances", "read_transactions"], "locations": ["https://example.com/accounts"] }, { "type": "payment_initiation", "actions": ["initiate", "status", "cancel"], "locations": ["https://example.com/payments"], "instructedAmount": {"currency": "EUR", "amount": "123.50"}, "creditorName": "Merchant A", "creditorAccount": {"iban": "DE02100100109307118603"}, "remittanceInformationUnstructured": "Ref Number Merchant" } ] ``` -------------------------------- ### Introspection response parsing Source: https://github.com/hstern/go-rar/blob/main/README.md Parses an introspection response and extracts authorization details. ```go var resp struct { Active bool `json:"active"` Scope string `json:"scope,omitempty"` ClientID string `json:"client_id,omitempty"` AuthorizationDetails json.RawMessage `json:"authorization_details,omitempty"` } if err := json.NewDecoder(httpResp.Body).Decode(&resp); err != nil { log.Fatal(err) } details, err := rar.ParseArray(resp.AuthorizationDetails) if err != nil { log.Fatal(err) } _ = details ``` -------------------------------- ### token_response.json — RFC 9396 §7 Source: https://github.com/hstern/go-rar/blob/main/internal/specfixtures/README.md The full OAuth token-response envelope. Stored whole (not just the authorization_details array) so the conformance test can extract the array, round-trip it, and confirm it slots back into the envelope identically. ```json { "access_token": "2YotnFZFEjr1zCsicMWpAA", "token_type": "Bearer", "expires_in": 3600, "refresh_token": "tGzv3JOkF0XG5Qx2TlKWIA", "authorization_details": [ { "type": "payment_initiation", "actions": ["initiate"], "locations": ["https://example.com/payments"], "instructedAmount": {"currency": "EUR", "amount": "123.50"}, "creditorName": "Merchant A" } ] } ``` -------------------------------- ### baseline.json — RFC 9396 §2 Source: https://github.com/hstern/go-rar/blob/main/internal/specfixtures/README.md A single type-only–plus–common-members detail, wrapped in a one-element array. The wire shape is always an array, even with a single detail. ```json [ { "type": "customer_information", "locations": ["https://example.com/customers"], "actions": ["read", "write"], "datatypes": ["contacts", "photos"] } ] ``` -------------------------------- ### introspection.json — RFC 9396 §9 Source: https://github.com/hstern/go-rar/blob/main/internal/specfixtures/README.md The full OAuth introspection-response envelope. Same rationale as token_response.json — the envelope is part of the fixture so the conformance test exercises the realistic extract-and-reembed shape. ```json { "active": true, "sub": "24400320", "aud": "s6BhdRkqt3", "iss": "https://server.example.com/", "exp": 1419356238, "authorization_details": [ { "type": "account_information", "actions": ["read"], "locations": ["https://example.com/accounts"] } ] } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.