Resource Access (via Tags)
Tags consist of a key and value pair, and are part of a resource’s meta-data. Tags are used to ensure that API resources that belong to a set of principals are only accessible by those principals. Tags and Roles complement each other to create a powerful, yet simple authorization strategy. Roles capture what API operations can be performed by a principal, and Tags capture which resources are accessible to a set of principals. SaaS developers store Tags for resources created by their customers, and customers attach Tags to authorization principals to be used in authorization.
Set Tags on Resources
In order for tag-based authorization to work, tags must be applied on a customer's resources managed by a SaaS (API) service, and attached to authorization principals that can operate on those resources. For example, a user (a principal) in the marketing department (a tag) should only be able to operate only on the marketing departments’ expense sheets (a resource). API subscribers can apply tags to Users, Client Keys and Roles via the Katanemo API Service Console or via the Katanemo SDK. Tag key/value pairs are set in the JWT session token generated by Katanemo for the principal and matched against tags available on the OpenAPI defined resource.
Note: If you are using an OIDC-compliant Idp integration with Katanemo (via Connections), you will need to ensure that the session token generated by the IDP includes tags for Katanemo to perform authorization against for federated users.
Tag Storage in Katanemo
Katanemo offers a tagging API for developers to easily store tags for resources created by an API Subscriber. With the Tagging API, developers offload undifferentiated ABAC (attribute-based authorization control) infrastructure muck so that they can continue to focus just on what matters most to their business: building capabilities on behalf of their customers.
Katanemo’s focus on OpenAPI (once again) makes the storage and retrieval of resource Tags simple. With an OpenAPI spec developers can neatly capture resource schemas, and Katanemo uses those schemas to store and retrieve Tags.
...
paths:
"/catalog/images/{imageId}":
get:
operationId: getImage
parameters:
- name: imageId
in: path
required: true
schema:
type: string
pattern: ^[a-zA-Z0-9\-]{3,128}$
For example, the OpenAPI spec above captures the definition of an {imageId}
resource. Developers simply call the Tagging API with the imageId resource name, a resource id, and list of tags that must be associated with that image resource. For example, when a user calls the API /catalog/images/12345
, Katanemo matches session token tags with tags on that image resource. If all the tags associated with the image resource 12345 match tags in the session token of the principal, then the authorization evaluation logic proceeds to the next step.
Tags consist of a key name and a value, and the following restrictions apply to tags:
- Resource names must be fully qualified in the OpenAPI specification
- Resource ids should be unique and must match the schema defined in the OpenAPI specification
- You can optionally pass in a namespace qualifier if resource ids are not globally scoped. The combination of namespace and resource id must be unique so that Katanemo can store and retrieve tags effectively
- Maximum tag key length: 127 Unicode characters in UTF-8
- Maximum tag value length: 255 Unicode characters in UTF-8. You can also include a list of tag values for a unique tag key via the
[]
directive. For example:“department": [ "finance", "hr", "legal" ].
- Tag keys and values are case insensitive.
- Maximum number of tag keys per resource: 50
Access Tags
The above approach is commonly referred to as attribute-based access control. Tags are essentially attributes of principals (for e.g. a User) and resources. This works well for access control mechanisms of resources belonging to a single (domain) subscriber account - they can apply tags to their resources and principals without friction. But this approach becomes cumbersome if resources owned by one account should be accessible to other accounts. For example, Katanemo’s Service resource is owned by an API developer (a subscriber of Katanemo), but how should an API developer give access to select Service(s) to other potential subscribers?
Traditionally, access and authorization mechanisms are buried deep in complex code paths with clunky if/else statements, but Katanemo solves this problem elegantly via Access Tags: RESTful access semantics encoded as tags to enable cross account resource sharing in simple, yet strictly-accurate ways.
For example, when you want to make your OpenAPI Service instance accessible to anyone, simply add the following tag to your Service instance:
access-tag:GET:*principals:[*]
In the above example, access-tag:GET:*
allows GET operations on any RESTful path to the resource, {serviceId}
is the Service resource to which access is being granted. And, principals
are authorization principals to whom access should be granted; [*]
denotes anyone. Now, when a potential subscriber navigates to https://Katanemo.com/sign-up/{service-id}, Katanemo grants access to that sign-up page.
System Defined Access Tags
To facilitate critical interactions between SaaS developers and their customers, you’ll notice that Katanemo adds tags on select Katanemo API resources (like /org/{accountId}). These system-defined Access Tags can only be updated or deleted by Katanemo.
For example, when a customer creates a Role for a particular SaaS service, the Role resource is owned by that customer. But developers must be able to get Role details so that their ARC instances can pull role policies and perform auth(z). Katanemo adds the following Access Tag:
katanemo:access-tag:GET:*:{role-id}:prinicipals=[999113]
999113 is the Katanemo account ID of the developer that needs policy details of the Role owned by their customer.