Update module path to github.com/Elydora-Infrastructure/Elydora-Go-SDK
- Update go.mod module path - Update all import references - Update README install and import examples Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
fdae7e9a18
commit
0fdedb7247
13 files changed
+38
-99
No files matched your search
@@ -24,3 +24,10 @@ go.work.sum
|
|||||||
# OS
|
# OS
|
||||||
.DS_Store
|
.DS_Store
|
||||||
Thumbs.db
|
Thumbs.db
|
||||||
|
|
||||||
|
# Environment and secrets
|
||||||
|
.env
|
||||||
|
.env.*
|
||||||
|
.env.local
|
||||||
|
*.pem
|
||||||
|
*.key
|
||||||
@@ -5,7 +5,7 @@ Official Go SDK for the [Elydora](https://elydora.com) tamper-evident audit plat
|
|||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
go get github.com/elydora/sdk-go
|
go get github.com/Elydora-Infrastructure/Elydora-Go-SDK
|
||||||
```
|
```
|
||||||
|
|
||||||
Requires Go 1.21+. Zero third-party dependencies (stdlib only).
|
Requires Go 1.21+. Zero third-party dependencies (stdlib only).
|
||||||
@@ -19,7 +19,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
elydora "github.com/elydora/sdk-go"
|
elydora "github.com/Elydora-Infrastructure/Elydora-Go-SDK"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
@@ -64,7 +64,7 @@ func main() {
|
|||||||
The SDK includes a CLI for installing audit hooks into AI coding agents.
|
The SDK includes a CLI for installing audit hooks into AI coding agents.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
go install github.com/elydora/sdk-go/cmd/elydora@latest
|
go install github.com/Elydora-Infrastructure/Elydora-Go-SDK/cmd/elydora@latest
|
||||||
|
|
||||||
elydora install \
|
elydora install \
|
||||||
--agent claudecode \
|
--agent claudecode \
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import "fmt"
|
|||||||
// RegisterAgent registers a new AI agent within the organization.
|
// RegisterAgent registers a new AI agent within the organization.
|
||||||
func (c *Client) RegisterAgent(req *RegisterAgentRequest) (*RegisterAgentResponse, error) {
|
func (c *Client) RegisterAgent(req *RegisterAgentRequest) (*RegisterAgentResponse, error) {
|
||||||
var result RegisterAgentResponse
|
var result RegisterAgentResponse
|
||||||
if err := c.doPost("/agents", req, &result); err != nil {
|
if err := c.doPost("/v1/agents/register", req, &result); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &result, nil
|
return &result, nil
|
||||||
@@ -14,7 +14,7 @@ func (c *Client) RegisterAgent(req *RegisterAgentRequest) (*RegisterAgentRespons
|
|||||||
// GetAgent retrieves an agent by ID.
|
// GetAgent retrieves an agent by ID.
|
||||||
func (c *Client) GetAgent(agentID string) (*GetAgentResponse, error) {
|
func (c *Client) GetAgent(agentID string) (*GetAgentResponse, error) {
|
||||||
var result GetAgentResponse
|
var result GetAgentResponse
|
||||||
if err := c.doGet(fmt.Sprintf("/agents/%s", agentID), &result); err != nil {
|
if err := c.doGet(fmt.Sprintf("/v1/agents/%s", agentID), &result); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &result, nil
|
return &result, nil
|
||||||
@@ -22,14 +22,14 @@ func (c *Client) GetAgent(agentID string) (*GetAgentResponse, error) {
|
|||||||
|
|
||||||
// FreezeAgent freezes an agent, preventing it from submitting operations.
|
// FreezeAgent freezes an agent, preventing it from submitting operations.
|
||||||
func (c *Client) FreezeAgent(agentID, reason string) error {
|
func (c *Client) FreezeAgent(agentID, reason string) error {
|
||||||
return c.doPost(fmt.Sprintf("/agents/%s/freeze", agentID), &FreezeAgentRequest{
|
return c.doPost(fmt.Sprintf("/v1/agents/%s/freeze", agentID), &FreezeAgentRequest{
|
||||||
Reason: reason,
|
Reason: reason,
|
||||||
}, nil)
|
}, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
// RevokeKey revokes a specific key for an agent.
|
// RevokeKey revokes a specific key for an agent.
|
||||||
func (c *Client) RevokeKey(agentID, kid, reason string) error {
|
func (c *Client) RevokeKey(agentID, kid, reason string) error {
|
||||||
return c.doPost(fmt.Sprintf("/agents/%s/revoke-key", agentID), &RevokeAgentRequest{
|
return c.doPost(fmt.Sprintf("/v1/agents/%s/revoke", agentID), &RevokeAgentRequest{
|
||||||
KID: kid,
|
KID: kid,
|
||||||
Reason: reason,
|
Reason: reason,
|
||||||
}, nil)
|
}, nil)
|
||||||
|
|||||||
@@ -1,43 +1,9 @@
|
|||||||
package elydora
|
package elydora
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"net/url"
|
|
||||||
"strconv"
|
|
||||||
)
|
|
||||||
|
|
||||||
// QueryAudit queries the audit log with the given parameters.
|
// QueryAudit queries the audit log with the given parameters.
|
||||||
func (c *Client) QueryAudit(params *AuditQueryRequest) (*AuditQueryResponse, error) {
|
func (c *Client) QueryAudit(params *AuditQueryRequest) (*AuditQueryResponse, error) {
|
||||||
q := url.Values{}
|
|
||||||
if params.OrgID != "" {
|
|
||||||
q.Set("org_id", params.OrgID)
|
|
||||||
}
|
|
||||||
if params.AgentID != "" {
|
|
||||||
q.Set("agent_id", params.AgentID)
|
|
||||||
}
|
|
||||||
if params.OperationType != "" {
|
|
||||||
q.Set("operation_type", params.OperationType)
|
|
||||||
}
|
|
||||||
if params.StartTime != nil {
|
|
||||||
q.Set("start_time", strconv.FormatInt(*params.StartTime, 10))
|
|
||||||
}
|
|
||||||
if params.EndTime != nil {
|
|
||||||
q.Set("end_time", strconv.FormatInt(*params.EndTime, 10))
|
|
||||||
}
|
|
||||||
if params.Cursor != "" {
|
|
||||||
q.Set("cursor", params.Cursor)
|
|
||||||
}
|
|
||||||
if params.Limit != nil {
|
|
||||||
q.Set("limit", strconv.Itoa(*params.Limit))
|
|
||||||
}
|
|
||||||
|
|
||||||
path := "/audit"
|
|
||||||
if encoded := q.Encode(); encoded != "" {
|
|
||||||
path = fmt.Sprintf("/audit?%s", encoded)
|
|
||||||
}
|
|
||||||
|
|
||||||
var result AuditQueryResponse
|
var result AuditQueryResponse
|
||||||
if err := c.doGet(path, &result); err != nil {
|
if err := c.doPost("/v1/audit/query", params, &result); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &result, nil
|
return &result, nil
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ func Register(baseURL, email, password string, opts ...RegisterOption) (*AuthReg
|
|||||||
}
|
}
|
||||||
|
|
||||||
var result AuthRegisterResponse
|
var result AuthRegisterResponse
|
||||||
if err := authPost(baseURL, "/auth/register", req, &result); err != nil {
|
if err := authPost(baseURL, "/v1/auth/register", req, &result); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &result, nil
|
return &result, nil
|
||||||
@@ -62,7 +62,7 @@ func Login(baseURL, email, password string) (*AuthLoginResponse, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var result AuthLoginResponse
|
var result AuthLoginResponse
|
||||||
if err := authPost(baseURL, "/auth/login", req, &result); err != nil {
|
if err := authPost(baseURL, "/v1/auth/login", req, &result); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &result, nil
|
return &result, nil
|
||||||
@@ -91,7 +91,7 @@ func authPost(baseURL, path string, body interface{}, result interface{}) error
|
|||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
|
|
||||||
respBody, err := io.ReadAll(resp.Body)
|
respBody, err := io.ReadAll(io.LimitReader(resp.Body, 10<<20))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("elydora: read response body: %w", err)
|
return fmt.Errorf("elydora: read response body: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -116,7 +116,7 @@ func (c *Client) doRequest(method, path string, body interface{}, result interfa
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
respBody, err := io.ReadAll(resp.Body)
|
respBody, err := io.ReadAll(io.LimitReader(resp.Body, 10<<20))
|
||||||
resp.Body.Close()
|
resp.Body.Close()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
lastErr = fmt.Errorf("elydora: read response body: %w", err)
|
lastErr = fmt.Errorf("elydora: read response body: %w", err)
|
||||||
@@ -172,7 +172,7 @@ func (c *Client) doPost(path string, body interface{}, result interface{}) error
|
|||||||
return c.doRequest(http.MethodPost, path, body, result)
|
return c.doRequest(http.MethodPost, path, body, result)
|
||||||
}
|
}
|
||||||
|
|
||||||
// doPut performs a PUT request.
|
// SetToken sets the JWT token used for authenticated API requests.
|
||||||
func (c *Client) doPut(path string, body interface{}, result interface{}) error {
|
func (c *Client) SetToken(token string) {
|
||||||
return c.doRequest(http.MethodPut, path, body, result)
|
c.token = token
|
||||||
}
|
}
|
||||||
+1
-1
@@ -8,7 +8,7 @@ import (
|
|||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/elydora/sdk-go/cmd/elydora/plugins"
|
"github.com/Elydora-Infrastructure/Elydora-Go-SDK/cmd/elydora/plugins"
|
||||||
)
|
)
|
||||||
|
|
||||||
const version = "1.0.0"
|
const version = "1.0.0"
|
||||||
|
|||||||
@@ -32,13 +32,6 @@ func computePayloadHash(payload interface{}) (string, error) {
|
|||||||
return sha256BytesBase64url([]byte(canonical)), nil
|
return sha256BytesBase64url([]byte(canonical)), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// computeChainHash computes the chain hash for an operation.
|
|
||||||
// Formula: SHA-256(prev_chain_hash + "|" + payload_hash + "|" + operation_id + "|" + issued_at)
|
|
||||||
func computeChainHash(prevChainHash, payloadHash, operationID string, issuedAt int64) string {
|
|
||||||
input := prevChainHash + "|" + payloadHash + "|" + operationID + "|" + fmt.Sprintf("%d", issuedAt)
|
|
||||||
return sha256Base64url(input)
|
|
||||||
}
|
|
||||||
|
|
||||||
// signEd25519 signs data with an Ed25519 private key seed (base64url-encoded 32 bytes).
|
// signEd25519 signs data with an Ed25519 private key seed (base64url-encoded 32 bytes).
|
||||||
// Returns the signature as base64url.
|
// Returns the signature as base64url.
|
||||||
func signEd25519(privateKeyBase64url string, data []byte) (string, error) {
|
func signEd25519(privateKeyBase64url string, data []byte) (string, error) {
|
||||||
@@ -54,37 +47,6 @@ func signEd25519(privateKeyBase64url string, data []byte) (string, error) {
|
|||||||
return base64urlEncode(sig), nil
|
return base64urlEncode(sig), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// verifyEd25519 verifies an Ed25519 signature.
|
|
||||||
func verifyEd25519(publicKeyBase64url string, signatureBase64url string, data []byte) (bool, error) {
|
|
||||||
pubBytes, err := base64urlDecode(publicKeyBase64url)
|
|
||||||
if err != nil {
|
|
||||||
return false, fmt.Errorf("decode public key: %w", err)
|
|
||||||
}
|
|
||||||
if len(pubBytes) != ed25519.PublicKeySize {
|
|
||||||
return false, fmt.Errorf("public key must be %d bytes, got %d", ed25519.PublicKeySize, len(pubBytes))
|
|
||||||
}
|
|
||||||
sigBytes, err := base64urlDecode(signatureBase64url)
|
|
||||||
if err != nil {
|
|
||||||
return false, fmt.Errorf("decode signature: %w", err)
|
|
||||||
}
|
|
||||||
return ed25519.Verify(ed25519.PublicKey(pubBytes), data, sigBytes), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// derivePublicKey derives the Ed25519 public key from a private key seed (base64url).
|
|
||||||
// Returns the public key as base64url.
|
|
||||||
func derivePublicKey(privateKeyBase64url string) (string, error) {
|
|
||||||
seed, err := base64urlDecode(privateKeyBase64url)
|
|
||||||
if err != nil {
|
|
||||||
return "", fmt.Errorf("decode private key: %w", err)
|
|
||||||
}
|
|
||||||
if len(seed) != ed25519.SeedSize {
|
|
||||||
return "", fmt.Errorf("private key seed must be %d bytes, got %d", ed25519.SeedSize, len(seed))
|
|
||||||
}
|
|
||||||
key := ed25519.NewKeyFromSeed(seed)
|
|
||||||
pub := key.Public().(ed25519.PublicKey)
|
|
||||||
return base64urlEncode(pub), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// JCS Canonicalization (RFC 8785)
|
// JCS Canonicalization (RFC 8785)
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import "fmt"
|
|||||||
// ListEpochs lists all epochs for the organization.
|
// ListEpochs lists all epochs for the organization.
|
||||||
func (c *Client) ListEpochs() (*ListEpochsResponse, error) {
|
func (c *Client) ListEpochs() (*ListEpochsResponse, error) {
|
||||||
var result ListEpochsResponse
|
var result ListEpochsResponse
|
||||||
if err := c.doGet("/epochs", &result); err != nil {
|
if err := c.doGet("/v1/epochs", &result); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &result, nil
|
return &result, nil
|
||||||
@@ -14,7 +14,7 @@ func (c *Client) ListEpochs() (*ListEpochsResponse, error) {
|
|||||||
// GetEpoch retrieves a specific epoch by ID.
|
// GetEpoch retrieves a specific epoch by ID.
|
||||||
func (c *Client) GetEpoch(epochID string) (*GetEpochResponse, error) {
|
func (c *Client) GetEpoch(epochID string) (*GetEpochResponse, error) {
|
||||||
var result GetEpochResponse
|
var result GetEpochResponse
|
||||||
if err := c.doGet(fmt.Sprintf("/epochs/%s", epochID), &result); err != nil {
|
if err := c.doGet(fmt.Sprintf("/v1/epochs/%s", epochID), &result); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &result, nil
|
return &result, nil
|
||||||
|
|||||||
+3
-3
@@ -5,7 +5,7 @@ import "fmt"
|
|||||||
// CreateExport creates a new compliance export job.
|
// CreateExport creates a new compliance export job.
|
||||||
func (c *Client) CreateExport(params *CreateExportRequest) (*CreateExportResponse, error) {
|
func (c *Client) CreateExport(params *CreateExportRequest) (*CreateExportResponse, error) {
|
||||||
var result CreateExportResponse
|
var result CreateExportResponse
|
||||||
if err := c.doPost("/exports", params, &result); err != nil {
|
if err := c.doPost("/v1/exports", params, &result); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &result, nil
|
return &result, nil
|
||||||
@@ -14,7 +14,7 @@ func (c *Client) CreateExport(params *CreateExportRequest) (*CreateExportRespons
|
|||||||
// ListExports lists all exports for the organization.
|
// ListExports lists all exports for the organization.
|
||||||
func (c *Client) ListExports() (*ListExportsResponse, error) {
|
func (c *Client) ListExports() (*ListExportsResponse, error) {
|
||||||
var result ListExportsResponse
|
var result ListExportsResponse
|
||||||
if err := c.doGet("/exports", &result); err != nil {
|
if err := c.doGet("/v1/exports", &result); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &result, nil
|
return &result, nil
|
||||||
@@ -23,7 +23,7 @@ func (c *Client) ListExports() (*ListExportsResponse, error) {
|
|||||||
// GetExport retrieves a specific export by ID.
|
// GetExport retrieves a specific export by ID.
|
||||||
func (c *Client) GetExport(exportID string) (*GetExportResponse, error) {
|
func (c *Client) GetExport(exportID string) (*GetExportResponse, error) {
|
||||||
var result GetExportResponse
|
var result GetExportResponse
|
||||||
if err := c.doGet(fmt.Sprintf("/exports/%s", exportID), &result); err != nil {
|
if err := c.doGet(fmt.Sprintf("/v1/exports/%s", exportID), &result); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &result, nil
|
return &result, nil
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
module github.com/elydora/sdk-go
|
module github.com/Elydora-Infrastructure/Elydora-Go-SDK
|
||||||
|
|
||||||
go 1.21
|
go 1.21
|
||||||
@@ -3,7 +3,7 @@ package elydora
|
|||||||
// GetJWKS retrieves the JSON Web Key Set from the Elydora API.
|
// GetJWKS retrieves the JSON Web Key Set from the Elydora API.
|
||||||
func (c *Client) GetJWKS() (*JWKSResponse, error) {
|
func (c *Client) GetJWKS() (*JWKSResponse, error) {
|
||||||
var result JWKSResponse
|
var result JWKSResponse
|
||||||
if err := c.doGet("/.well-known/jwks.json", &result); err != nil {
|
if err := c.doGet("/.well-known/elydora/jwks.json", &result); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &result, nil
|
return &result, nil
|
||||||
|
|||||||
+8
-4
@@ -2,6 +2,10 @@ package elydora
|
|||||||
|
|
||||||
import "fmt"
|
import "fmt"
|
||||||
|
|
||||||
|
// GenesisChainHash is the initial chain hash for an agent's first operation.
|
||||||
|
// It is the base64url encoding of 32 zero bytes, matching the backend.
|
||||||
|
const GenesisChainHash = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
|
||||||
|
|
||||||
// CreateOperation builds a signed EOR from the given parameters.
|
// CreateOperation builds a signed EOR from the given parameters.
|
||||||
// It generates a UUIDv7 operation ID, a nonce, computes the payload hash and chain hash,
|
// It generates a UUIDv7 operation ID, a nonce, computes the payload hash and chain hash,
|
||||||
// and signs the entire record with the client's private key.
|
// and signs the entire record with the client's private key.
|
||||||
@@ -29,7 +33,7 @@ func (c *Client) CreateOperation(params *CreateOperationParams) (*EOR, error) {
|
|||||||
|
|
||||||
prevChainHash := params.PrevChainHash
|
prevChainHash := params.PrevChainHash
|
||||||
if prevChainHash == "" {
|
if prevChainHash == "" {
|
||||||
prevChainHash = "GENESIS"
|
prevChainHash = GenesisChainHash
|
||||||
}
|
}
|
||||||
|
|
||||||
kid := params.KID
|
kid := params.KID
|
||||||
@@ -66,7 +70,7 @@ func (c *Client) CreateOperation(params *CreateOperationParams) (*EOR, error) {
|
|||||||
// SubmitOperation submits a signed EOR to the Elydora API.
|
// SubmitOperation submits a signed EOR to the Elydora API.
|
||||||
func (c *Client) SubmitOperation(eor *EOR) (*SubmitOperationResponse, error) {
|
func (c *Client) SubmitOperation(eor *EOR) (*SubmitOperationResponse, error) {
|
||||||
var result SubmitOperationResponse
|
var result SubmitOperationResponse
|
||||||
if err := c.doPost("/operations", eor, &result); err != nil {
|
if err := c.doPost("/v1/operations", eor, &result); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &result, nil
|
return &result, nil
|
||||||
@@ -75,7 +79,7 @@ func (c *Client) SubmitOperation(eor *EOR) (*SubmitOperationResponse, error) {
|
|||||||
// GetOperation retrieves an operation by ID.
|
// GetOperation retrieves an operation by ID.
|
||||||
func (c *Client) GetOperation(operationID string) (*GetOperationResponse, error) {
|
func (c *Client) GetOperation(operationID string) (*GetOperationResponse, error) {
|
||||||
var result GetOperationResponse
|
var result GetOperationResponse
|
||||||
if err := c.doGet(fmt.Sprintf("/operations/%s", operationID), &result); err != nil {
|
if err := c.doGet(fmt.Sprintf("/v1/operations/%s", operationID), &result); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &result, nil
|
return &result, nil
|
||||||
@@ -84,7 +88,7 @@ func (c *Client) GetOperation(operationID string) (*GetOperationResponse, error)
|
|||||||
// VerifyOperation verifies the integrity of an operation.
|
// VerifyOperation verifies the integrity of an operation.
|
||||||
func (c *Client) VerifyOperation(operationID string) (*VerifyOperationResponse, error) {
|
func (c *Client) VerifyOperation(operationID string) (*VerifyOperationResponse, error) {
|
||||||
var result VerifyOperationResponse
|
var result VerifyOperationResponse
|
||||||
if err := c.doGet(fmt.Sprintf("/operations/%s/verify", operationID), &result); err != nil {
|
if err := c.doPost(fmt.Sprintf("/v1/operations/%s/verify", operationID), nil, &result); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &result, nil
|
return &result, nil
|
||||||
|
|||||||
Reference in new issue
Block a user