careful-honey-27437
09/09/2025, 9:13 AMchilly-king-10285
09/09/2025, 9:13 AMchilly-king-10285
09/09/2025, 9:13 AMcareful-honey-27437
09/09/2025, 9:14 AMcareful-honey-27437
09/09/2025, 9:15 AMchilly-king-10285
09/09/2025, 9:15 AMchilly-king-10285
09/09/2025, 9:15 AMcareful-honey-27437
09/09/2025, 9:17 AMchilly-king-10285
09/09/2025, 9:17 AMchilly-king-10285
09/09/2025, 9:17 AMcareful-honey-27437
09/09/2025, 9:20 AMchilly-king-10285
09/09/2025, 9:20 AMchilly-king-10285
09/09/2025, 9:20 AMgo package main import ( "context" "fmt" "net/http" "os" ory "<http://github.com/ory/client-go|github.com/ory/client-go>" ) func main() { // Example tuple: Blog:secret_post#view@Bob namespace := "Blog" object := "secret_post" relation := "view" subjectId := "Bob" // Auth: export ORY_API_KEY before running ctx := context.WithValue(context.Background(), ory.ContextAccessToken, os.Getenv("ORY_API_KEY")) // Point to your Ory Network project URL cfg := ory.NewConfiguration() cfg.Servers = []ory.ServerConfiguration{{ URL: "<https://your-project.slug.projects.oryapis.com>", }} api := ory.NewAPIClient(cfg) // Prepare create payload body := ory.CreateRelationshipBody{ Namespace: &namespace, Object: &object, Relation: &relation, SubjectId: &subjectId, } // Attempt to create the relationship _, resp, err := api.RelationshipApi. CreateRelationship(ctx). CreateRelationshipBody(body). Execute() if err != nil { // We don't have a documented "duplicate" code; handle generically. // If you want to detect "already exists", do a follow-up check below. fmt.Printf("CreateRelationship error: %v (status: %v)\n", err, statusOf(resp)) } else { // Typically 201 when created fmt.Printf("CreateRelationship success (status: %v)\n", statusOf(resp)) } // “Somehow indicate” it already exists: // Perform a permission check. If allowed == true, the tuple is present, // meaning either it was created now or it already existed (duplicate no-op). check, resp2, err2 := api.PermissionApi. CheckPermission(ctx). Namespace(namespace). Object(object). Relation(relation). SubjectId(subjectId). Execute() if err2 != nil { fmt.Printf("CheckPermission error: %v (status: %v)\n", err2, statusOf(resp2)) return } if check.GetAllowed() { // At this point, you can treat this as “tuple exists”. // If CreateRelationship did not return 201 above, this likely indicates it already existed. fmt.Println("Tuple exists (permission allowed) — either created just now or already present.") } else { fmt.Println("Tuple does not exist (permission denied).") } } func statusOf(r *http.Response) int { if r == nil { return 0 } return r.StatusCode }
Notes: - The SDK method names and flow are based on the Ory Permissions (client-go) examples for CreateRelationship and CheckPermission. [[Permissions Go SDK](https://www.ory.sh/docs/keto/sdk/go)] - The upgrade guide shows the module/method names (RelationshipApi.CreateRelationship, PermissionApi.CheckPermission). [[SDK upgrade](https://www.ory.sh/docs/guides/upgrade/sdk-v1#permissions--access-control)] - The API references document CreateRelationship but do not specify a distinct “duplicate” status; duplicates are “ignored” in the gRPC write semantics, so the follow-up CheckPermission is a reliable way to confirm existence. [[createRelationship API](https://raw.githubusercontent.com/ory/docs/master/docs/reference/api.json); [write proto](https://www.ory.sh/docs/keto/reference/proto-api#oryketorelation_tuplesv1alpha2write_serviceproto)]careful-honey-27437
09/09/2025, 9:23 AMchilly-king-10285
09/09/2025, 9:23 AMchilly-king-10285
09/09/2025, 9:23 AMcareful-honey-27437
09/09/2025, 9:25 AM