> For the complete documentation index, see [llms.txt](https://docs.veza.com/4yItIzMvkpAvMVFAamTf/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.veza.com/4yItIzMvkpAvMVFAamTf/developers/api/oaa/dotnet-sdk.md).

# OAA .NET SDK

Building blocks for your custom OAA integration

{% hint style="info" %}
You can download the Veza C# SDK from [GitHub](https://github.com/Veza/oaaclient-csharp).
{% endhint %}

The `Veza` package provides data models, methods, and helpers for using the [Open Authorization API](https://github.com/Veza). It provides helper methods to populate OAA templates for custom applications, filesystems, HRIS systems, and identity providers, and push the payloads to Veza. The SDK can also be used as a generic Veza API client.

The `Veza` SDK includes the following core components:

* `Veza.Sdk.Client`: A base API client for making REST calls to a Veza tenant
* `Veza.OAA.Client`: An OAA API client for interacting with integration providers, data sources, and pushing OAA metadata to a Veza tenant.

For example usage, see [oaa-app-outline.md](/4yItIzMvkpAvMVFAamTf/developers/api/oaa/dotnet-sdk/oaa-app-outline.md).

**Sample Workflow**

Create the Veza API connection and a new custom application:

```c#
using Veza.OAA;
using Veza.OAA.Application;
using Veza.OAA.Base;

// inside namespace/class
            OAAClient oaaClient = new(api_key: <your_api_key>, url: <veza_tenant_url>);
            CustomApplication customApp = new(name: "sample app",
                applicationType: "sample", description: "This is a sample application");
```

Once the `CustomApplication` class is instantiated, you can use its public methods to populate the new app with users, groups, resources, and permissions metadata:

```c#
            // add custom permissions
            customApp.AddCustomPermission(name: "Admin", permissions: new List<Permission>
                {
                    Permission.DataRead,
                    Permission.DataWrite,
                    Permission.MetadataRead,
                    Permission.MetadataWrite,
                    Permission.NonData
                },
                applyToSubResources: true
            );

            // define custom user properties
            customApp.DefinedProperties[typeof(User)].DefineProperty("is_guest", typeof(bool));

            // add user
            User user = customApp.AddUser(name: "bob");
            user.AddIdentity("bob@example.com");
            user.IsActive = true;
            user.CreatedAt = "2001-01-01T00:00:00.000Z".FromRFC3339();
            user.DeactivatedAt = "2003-03-01T00:00:00.000Z".FromRFC3339();
            user.LastLoginAt = "2002-02-01T00:00:00.000Z".FromRFC3339();
            user.PasswordLastChangedAt = "2004-04-01T00:00:00.000Z".FromRFC3339();
            user.SetProperty(name: "is_guest", value: false);

            // define group properties
            customApp.DefinedProperties[typeof(Group)].DefineProperty("group_id", typeof(int));

            // add group
            Group group1 = customApp.AddGroup("group1");
            group1.CreatedAt = "2001-01-01T00:00:00.000Z".FromRFC3339();
            group1.SetProperty(name: "group_id", 1);
            customApp.Users["bob"].AddGroup("group1");
            Group group2 = customApp.AddGroup("group2");
            group2.AddGroup("group1");

            // idp identities
            customApp.AddIdPIdentity("user01@example.com");

            // define role properties
            customApp.DefinedProperties[typeof(Role)].DefineProperty("custom", typeof(bool));

            // add roles
            Role role1 = customApp.AddRole(name: "role1", permissions: new List<string> { "all", "Admin", "Manage_Thing" });
            role1.SetProperty(name: "custom", value: false);

            // define resource properties
            customApp.DefineResourceProperty("private", typeof(bool), "thing");

            // add resources
            Resource thing1 = customApp.AddResource(name: "thing1", resourceType: "thing", description: "thing1");
            thing1.SetProperty(name: "private", false);
            thing1.AddTag(name: "tag1", value: "This is a value @,-_.");
            Resource cog1 = thing1.AddSubResource(name: "cog1", resourceType: "cog");
            cog1.AddConnection(id: "service_account@some-project.iam.gserviceaccount.com", nodeType: "GoogleCloudServiceAccount");

            // authorizations
            customApp.Users["bob"].AddRole(name: "role1", applyToApplication: true);
            customApp.Groups["group2"].AddRole(name: "role1", resources: new List<Resource> { thing1 });
            customApp.IdPIdentities["user01@example.com"].AddRole(name: "role1", applyToApplication: true);

            return customApp;
```

Once all identities, permissions, and resources are added to the CustomApplication object, use the client connection to push the data to Veza:

```c#
    await oaaClient.CreateProvider(provider_name: "sample app", custom_template: "application");
    await oaaClient.PushApplication(provider_name: "sample app", data_source_name: "sample app 1", customApp);
```

See the [quickstarts](https://github.com/Veza/oaa-community/tree/main/quickstarts) directory for full examples.

#### Handling Errors

The `Veza.OAA` namespace provides exception types for common errors that occur when interacting with Veza APIs.

* An `OAAClientException` is raised if there are errors interacting with the Veza API.
* A `TemplateException` is raised if a provided payload does not conform to the template requirements. The inner exception will contain details about the exact issues encountered.

#### Additional Documentation

Each OAA connector will be slightly different, depending on the methods each source application or service provides for retrieving entities, authorization, and other required metadata. You should consult the API documentation for your application when considering how you will source the information, and refer to existing Veza-supported OAA connectors for real-world examples.

* OAA connector source code and `Veza` components are thoroughly annotated for reference when building your own integrations.
* For additional information about developing a custom OAA integration, please see [Open Authorization API](/4yItIzMvkpAvMVFAamTf/developers/api/oaa.md) section of the User Guide.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.veza.com/4yItIzMvkpAvMVFAamTf/developers/api/oaa/dotnet-sdk.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
