openapi: 3.0.3 info: title: Oso Cloud HTTP Centralized Authorization Data API version: 0.1.0 description: 'Oso Cloud exposes an HTTP API that you can use to make queries directly, without using one of the clients.For endpoints that require authentication, pass your API key as an HTTP Bearer Auth payload.For example, using curl: curl -H "Authorization: Bearer $OSO_AUTH" https://cloud.osohq.com/api/' servers: - url: https://api.osohq.com/api/ tags: - name: Centralized Authorization Data paths: /facts: post: tags: - Centralized Authorization Data description: 'Adds a new fact. DEPRECATED: Prefer `POST /batch` with payload `[{"inserts": []}]`.' operationId: post_facts requestBody: content: application/json: schema: $ref: '#/components/schemas/Fact' required: true responses: '200': description: '' content: application/json: schema: $ref: '#/components/schemas/Fact' default: description: '' content: application/json: schema: $ref: '#/components/schemas/ApiError' deprecated: true security: - ApiKey: [] x-codeSamples: - lang: javascript label: Node.js source: "import { Oso } from 'oso-cloud';\n\nconst apiKey = process.env.OSO_CLOUD_API_KEY;\nconst oso = new Oso(\"https://cloud.osohq.com\", apiKey);\n\n// Insert a single fact\nawait oso.insert([\n \"has_role\", \n { type: \"User\", id: \"alice\" }, \n \"maintainer\", \n { type: \"Repository\", id: \"anvils\" }\n]);\n" - lang: python label: Python source: 'import os from oso_cloud import Oso, Value oso = Oso(api_key=os.environ.get(''OSO_CLOUD_API_KEY'', None)) # Insert a single fact user = Value("User", "alice") repo = Value("Repository", "anvils") oso.insert(("has_role", user, "maintainer", repo)) ' - lang: go label: Go source: "package main\n\nimport (\n \"log\"\n \"os\"\n oso \"github.com/osohq/go-oso-cloud/v2\"\n)\n\nfunc main() {\n apiKey := os.Getenv(\"OSO_CLOUD_API_KEY\")\n osoClient := oso.NewClient(\"https://cloud.osohq.com\", apiKey)\n\n // Insert a single fact\n alice := oso.NewValue(\"User\", \"alice\")\n repo := oso.NewValue(\"Repository\", \"anvils\")\n err := osoClient.Insert(oso.NewFact(\"has_role\", alice, oso.String(\"maintainer\"), repo))\n if err != nil {\n log.Fatal(err)\n }\n}\n" - lang: java label: Java source: "package com.mycompany;\n\nimport java.io.IOException;\nimport com.osohq.oso_cloud.Oso;\nimport com.osohq.oso_cloud.api.ApiException;\nimport com.osohq.oso_cloud.api.Value;\n\npublic class App {\n public static void main(String[] args) {\n String apiKey = System.getenv(\"OSO_CLOUD_API_KEY\");\n Oso oso = new Oso(apiKey);\n \n try {\n // Insert a single fact\n Value user = new Value(\"User\", \"alice\");\n Value repo = new Value(\"Repository\", \"anvils\");\n oso.insert(\"has_role\", user, \"maintainer\", repo);\n } catch (IOException | ApiException e) {\n System.err.println(\"Error: \" + e.getMessage());\n }\n }\n}\n" - lang: ruby label: Ruby source: 'require ''oso-cloud'' api_key = ENV.fetch(''OSO_CLOUD_API_KEY'', nil) oso = OsoCloud::Oso.new(url: "https://cloud.osohq.com", api_key: api_key) # Insert a single fact user = OsoCloud::Value.new(type: "User", id: "alice") repo = OsoCloud::Value.new(type: "Repository", id: "anvils") oso.tell("has_role", user, "maintainer", repo) ' - lang: csharp label: C# source: 'using OsoCloud; string? apiKey = Environment.GetEnvironmentVariable("OSO_CLOUD_API_KEY"); var oso = new Oso("https://api.osohq.com", apiKey); // Insert a single fact var user = new Value("User", "alice"); var repo = new Value("Repository", "anvils"); await oso.Insert("has_role", user, "maintainer", repo); ' delete: tags: - Centralized Authorization Data description: 'Deletes a fact. Does not throw an error when the fact is not found. DEPRECATED: Prefer `POST /batch` with payload `[{"deletes": []}]`.' operationId: delete_facts requestBody: content: application/json: schema: $ref: '#/components/schemas/Fact' required: true responses: '200': description: '' content: application/json: schema: $ref: '#/components/schemas/ApiResult' default: description: '' content: application/json: schema: $ref: '#/components/schemas/ApiError' deprecated: true security: - ApiKey: [] x-codeSamples: - lang: javascript label: Node.js source: "import { Oso } from 'oso-cloud';\n\nconst apiKey = process.env.OSO_CLOUD_API_KEY;\nconst oso = new Oso(\"https://cloud.osohq.com\", apiKey);\n\n// Delete specific fact\nawait oso.delete([\n \"has_role\", \n { type: \"User\", id: \"alice\" }, \n \"maintainer\", \n { type: \"Repository\", id: \"anvils\" }\n]);\n\n// Delete using patterns (null = wildcard)\nawait oso.delete([\"has_role\", { type: \"User\", id: \"alice\" }, null, null]); // All roles for alice\n" - lang: python label: Python source: 'import os from oso_cloud import Oso, Value oso = Oso(api_key=os.environ.get(''OSO_CLOUD_API_KEY'', None)) # Delete specific fact user = Value("User", "alice") repo = Value("Repository", "anvils") oso.delete(("has_role", user, "maintainer", repo)) # Delete using patterns oso.delete(("has_role", user, None, None)) # All roles for user ' - lang: go label: Go source: "package main\n\nimport (\n \"log\"\n \"os\"\n oso \"github.com/osohq/go-oso-cloud/v2\"\n)\n\nfunc main() {\n apiKey := os.Getenv(\"OSO_CLOUD_API_KEY\")\n osoClient := oso.NewClient(\"https://cloud.osohq.com\", apiKey)\n\n// Delete specific fact\nuser := oso.NewValue(\"User\", \"alice\")\nrepo := oso.NewValue(\"Repository\", \"anvils\")\nerr := osoClient.Delete(oso.NewFact(\"has_role\", user, oso.String(\"maintainer\"), repo))\n\n// Delete using patterns\nerr = osoClient.Delete(oso.NewFactPattern(\n \"has_role\", \n user, \n nil, // Any role\n oso.NewValueOfType(\"Repository\") // Any repo\n))\n}\n" - lang: java label: Java source: "package com.mycompany;\n\nimport java.io.IOException;\nimport com.osohq.oso_cloud.Oso;\nimport com.osohq.oso_cloud.api.ApiException;\nimport com.osohq.oso_cloud.api.Value;\n\npublic class App {\n public static void main(String[] args) {\n String apiKey = System.getenv(\"OSO_CLOUD_API_KEY\");\n Oso oso = new Oso(apiKey);\n \n try {\n // Delete specific fact\n Value user = new Value(\"User\", \"alice\");\n Value repo = new Value(\"Repository\", \"anvils\");\n oso.delete(\"has_role\", user, \"maintainer\", repo);\n \n // Delete using patterns (null = wildcard)\n oso.delete(\"has_role\", user, null, null); // All roles for user\n } catch (IOException | ApiException e) {\n System.err.println(\"Error: \" + e.getMessage());\n }\n }\n}\n" - lang: ruby label: Ruby source: 'require ''oso-cloud'' api_key = ENV.fetch(''OSO_CLOUD_API_KEY'', nil) oso = OsoCloud::Oso.new(url: "https://cloud.osohq.com", api_key: api_key) # Delete specific fact user = OsoCloud::Value.new(type: "User", id: "alice") repo = OsoCloud::Value.new(type: "Repository", id: "anvils") oso.delete("has_role", user, "maintainer", repo) # Delete using patterns (nil = wildcard) oso.delete("has_role", user, nil, nil) # All roles for user ' - lang: csharp label: C# source: 'using OsoCloud; string? apiKey = Environment.GetEnvironmentVariable("OSO_CLOUD_API_KEY"); var oso = new Oso("https://api.osohq.com", apiKey); // Delete specific fact var user = new Value("User", "alice"); var repo = new Value("Repository", "anvils"); await oso.Delete("has_role", user, "maintainer", repo); // Delete using patterns (null = wildcard) await oso.Delete("has_role", user, null, null); // All roles for user ' /bulk_load: post: tags: - Centralized Authorization Data description: 'Adds many facts at once. DEPRECATED: Prefer `POST /batch` with payload `[{"inserts": }]`.' operationId: post_bulk_load requestBody: content: application/json: schema: type: array items: $ref: '#/components/schemas/Fact' required: true responses: '200': description: '' content: application/json: schema: $ref: '#/components/schemas/ApiResult' default: description: '' content: application/json: schema: $ref: '#/components/schemas/ApiError' deprecated: true security: - ApiKey: [] /bulk_delete: post: tags: - Centralized Authorization Data description: 'Delete many facts in a single transaction. DEPRECATED: Prefer `POST /batch` with payload `[{"deletes": }]`.' operationId: post_bulk_delete requestBody: content: application/json: schema: type: array items: $ref: '#/components/schemas/Fact' required: true responses: '200': description: '' content: application/json: schema: $ref: '#/components/schemas/ApiResult' default: description: '' content: application/json: schema: $ref: '#/components/schemas/ApiError' deprecated: true security: - ApiKey: [] /bulk: post: tags: - Centralized Authorization Data description: 'Deletes and adds many facts in one atomic transaction. The deletions are performed before the adds. `null` can be used as a wildcard in facts in delete. Does not throw an error when the facts to delete are not found. DEPRECATED: Prefer `POST /batch` with payload `[{"deletes": }, {"inserts": }]`.' operationId: post_bulk requestBody: content: application/json: schema: $ref: '#/components/schemas/Bulk' required: true responses: '200': description: '' content: application/json: schema: $ref: '#/components/schemas/ApiResult' default: description: '' content: application/json: schema: $ref: '#/components/schemas/ApiError' deprecated: true security: - ApiKey: [] /batch: post: tags: - Centralized Authorization Data description: 'Deletes and adds many facts in one atomic batch. Facts are inserted and deleted in-order (ie: `insert`ed facts may be `delete`d in the same transaction). `null` can be used as a wildcard in deleted facts. Does not throw an error when the facts to delete are not found.' operationId: post_batch requestBody: content: application/json: schema: type: array items: $ref: '#/components/schemas/FactChangeset' required: true responses: '200': description: '' content: application/json: schema: $ref: '#/components/schemas/ApiResult' default: description: '' content: application/json: schema: $ref: '#/components/schemas/ApiError' security: - ApiKey: [] x-codeSamples: - lang: javascript label: Node.js source: "import { Oso } from 'oso-cloud';\n\nconst apiKey = process.env.OSO_CLOUD_API_KEY;\nconst oso = new Oso(\"https://cloud.osohq.com\", apiKey);\n\n// Batch multiple operations\nconst user = { type: \"User\", id: \"alice\" };\nconst org = { type: \"Organization\", id: \"acme\" };\nconst repo = { type: \"Repository\", id: \"anvils\" };\n\nawait oso.batch((tx) => {\n // Insert new facts\n tx.insert([\"has_role\", user, \"owner\", org]);\n tx.insert([\"has_permission\", user, \"admin\", repo]);\n \n // Delete old facts\n tx.delete([\"has_role\", user, \"maintainer\", repo]);\n tx.delete([\"has_role\", user, \"member\", org]);\n});\n" - lang: python label: Python source: "import os\nfrom oso_cloud import Oso, Value\n\noso = Oso(api_key=os.environ.get('OSO_CLOUD_API_KEY', None))\n\n# Batch multiple operations\nuser = Value(\"User\", \"alice\")\norg = Value(\"Organization\", \"acme\")\nrepo = Value(\"Repository\", \"anvils\")\n\nwith oso.batch() as tx:\n # Insert new facts\n tx.insert((\"has_role\", user, \"owner\", org))\n tx.insert((\"has_permission\", user, \"admin\", repo))\n \n # Delete old facts\n tx.delete((\"has_role\", user, \"maintainer\", repo))\n tx.delete((\"has_role\", user, \"member\", org))\n" - lang: go label: Go source: "package main\n\nimport (\n \"log\"\n \"os\"\n oso \"github.com/osohq/go-oso-cloud/v2\"\n)\n\nfunc main() {\n apiKey := os.Getenv(\"OSO_CLOUD_API_KEY\")\n osoClient := oso.NewClient(\"https://cloud.osohq.com\", apiKey)\n\n// Batch multiple operations\nuser := oso.NewValue(\"User\", \"alice\")\norg := oso.NewValue(\"Organization\", \"acme\")\nrepo := oso.NewValue(\"Repository\", \"anvils\")\n\nerr := osoClient.Batch(func(tx oso.BatchTransaction) {\n // Insert new facts\n tx.Insert(oso.NewFact(\"has_role\", user, oso.String(\"owner\"), org))\n tx.Insert(oso.NewFact(\"has_permission\", user, oso.String(\"admin\"), repo))\n \n // Delete old facts\n tx.Delete(oso.NewFact(\"has_role\", user, oso.String(\"maintainer\"), repo))\n tx.Delete(oso.NewFactPattern(\"has_role\", user, nil, org))\n})\nif err != nil {\n log.Fatal(err)\n}\n}\n" - lang: java label: Java source: "package com.mycompany;\n\nimport java.io.IOException;\nimport com.osohq.oso_cloud.Oso;\nimport com.osohq.oso_cloud.api.ApiException;\nimport com.osohq.oso_cloud.api.Value;\n\npublic class App {\n public static void main(String[] args) {\n String apiKey = System.getenv(\"OSO_CLOUD_API_KEY\");\n Oso oso = new Oso(apiKey);\n \n try {\n // Batch multiple operations\n Value user = new Value(\"User\", \"alice\");\n Value org = new Value(\"Organization\", \"acme\");\n Value repo = new Value(\"Repository\", \"anvils\");\n \n oso.batch((tx) -> {\n // Insert new facts\n tx.insert(\"has_role\", user, \"owner\", org);\n tx.insert(\"has_permission\", user, \"admin\", repo);\n \n // Delete old facts\n tx.delete(\"has_role\", user, \"maintainer\", repo);\n tx.delete(\"has_role\", user, \"member\", org);\n });\n } catch (IOException | ApiException e) {\n System.err.println(\"Error: \" + e.getMessage());\n }\n }\n}\n" - lang: ruby label: Ruby source: "require 'oso-cloud'\n\napi_key = ENV.fetch('OSO_CLOUD_API_KEY', nil)\noso = OsoCloud::Oso.new(url: \"https://cloud.osohq.com\", api_key: api_key)\n\n# Batch multiple operations\nuser = OsoCloud::Value.new(type: \"User\", id: \"alice\")\norg = OsoCloud::Value.new(type: \"Organization\", id: \"acme\")\nrepo = OsoCloud::Value.new(type: \"Repository\", id: \"anvils\")\n\noso.batch do |tx|\n # Insert new facts\n tx.tell(\"has_role\", user, \"owner\", org)\n tx.tell(\"has_permission\", user, \"admin\", repo)\n \n # Delete old facts\n tx.delete(\"has_role\", user, \"maintainer\", repo)\n tx.delete(\"has_role\", user, \"member\", org)\nend\n" - lang: csharp label: C# source: "using OsoCloud;\n\nstring? apiKey = Environment.GetEnvironmentVariable(\"OSO_CLOUD_API_KEY\");\nvar oso = new Oso(\"https://api.osohq.com\", apiKey);\n\n// Batch multiple operations\nvar user = new Value(\"User\", \"alice\");\nvar org = new Value(\"Organization\", \"acme\");\nvar repo = new Value(\"Repository\", \"anvils\");\n\nawait oso.Batch(tx => {\n // Insert new facts\n tx.Insert(\"has_role\", user, \"owner\", org);\n tx.Insert(\"has_permission\", user, \"admin\", repo);\n \n // Delete old facts\n tx.Delete(\"has_role\", user, \"maintainer\", repo);\n tx.Delete(\"has_role\", user, \"member\", org);\n});\n" /clear_data: post: tags: - Centralized Authorization Data operationId: clear_data responses: '200': description: '' content: application/json: schema: $ref: '#/components/schemas/ApiResult' default: description: '' content: application/json: schema: $ref: '#/components/schemas/ApiError' security: - ApiKey: [] components: schemas: ApiError: type: object required: - message properties: message: type: string ApiResult: type: object required: - message properties: message: type: string Value: type: object properties: type: type: string nullable: true id: type: string nullable: true Bulk: type: object required: - delete - tell properties: delete: type: array items: $ref: '#/components/schemas/Fact' tell: type: array items: $ref: '#/components/schemas/Fact' FactChangeset: description: A grouped run of facts to insert or delete. Inserted facts must contain concrete fact args, but deleted facts may contain wildcards. anyOf: - type: object required: - inserts properties: inserts: type: array items: $ref: '#/components/schemas/Fact' - type: object required: - deletes properties: deletes: type: array items: $ref: '#/components/schemas/Fact' Fact: description: 'A pattern object for matching authorization-relevant data, ie: facts.' type: object required: - args - predicate properties: predicate: type: string args: type: array items: $ref: '#/components/schemas/Value' securitySchemes: ApiKey: description: Requires an API key to access. type: http scheme: bearer bearerFormat: Bearer e_0123_123_token0123