What news from AWS re:Invent last week will have the most impact on you?
Amazon Q, an AI chatbot for explaining how AWS works.
Super-fast S3 Express storage.
New Graviton 4 processor instances.
Emily Freeman leaving AWS.
I don't use AWS, so none of this will affect me.
API Management / Security

Secure Go APIs with Decentralized Identity Tokens, Part 2

Claims are a vital component of modern authentication and authorization systems: establishing the identity of users, determining their access privileges, and ensuring personalized service delivery. Read the second installment of a three-part series on securing Go APIs.
Sep 28th, 2023 3:00am by
Featued image for: Secure Go APIs with Decentralized Identity Tokens, Part 2
This article is the second of three-part series on the use of decentralized identity token to secure Go APIs. You can read part one here and part three here.

Claims are a vital component of modern authentication and authorization systems, providing a structured representation of user attributes and permissions. In the context of securing Go APIs, claims play a crucial role in establishing the identity of users, determining their roles and access privileges, and ensuring personalized service delivery.

By encapsulating relevant user information in a standardized format, claims enable seamless communication between clients and servers, leading to enhanced security, improved user experience and robust access-control mechanisms

Claims serve as a reliable means of identifying and authenticating users. By including unique identifiers and user attributes, such as names, emails, or custom fields, claims enable API endpoints to verify the legitimacy of incoming requests and establish the trustworthiness of users.

This, in turn, helps prevent unauthorized access attempts and potential security breaches. Leveraging claims in conjunction with token-based authentication, such as JWT (JSON Web Tokens), ensures that the user’s identity remains cryptographically verifiable, reducing the reliance on traditional username/password-based methods and enhancing the overall security posture of the API.

Moreover, claims provide a granular approach to managing user access and permissions in Go APIs. By embedding user roles, group affiliations and specific authorization rules within claims, APIs can enforce fine-grained access control, allowing or denying actions based on user entitlements.

This level of control not only prevents unauthorized access to sensitive endpoints or resources but also streamlines user interactions by presenting personalized content and services based on individual attributes.

Additionally, claims offer flexibility and extensibility, enabling APIs to cater to various user types and scenarios without modifying the core API logic, thereby simplifying maintenance and scalability while keeping security at the forefront of API design.

What Information Is Contained in Claims?

In decentralized identity tokens, claims typically include various types of information related to the user’s identity, roles and permissions. Some common types of information typically included in claims:

User identity. These provide information that uniquely identifies the user. Examples include:

Subject (sub): A unique identifier for the user, such as a user ID or username.

Name (name): The user’s full name.

Email (email): The user’s email address.

Issuer (iss): The entity that issued the token, usually an identity provider.

Roles and permissions. These define the user’s access rights and privileges. Examples include:

Role (role) – The user’s role within the system, such as admin, user, or moderator.

Permissions (permissions): A list of specific actions or operations the user is allowed to perform.

Scopes (scope) – Indicate the scope of access granted to the user, such as read, write, or execute permissions.

Personal attributes. These describe the user’s characteristics or properties. Examples include:

Date of Birth (dob): The user’s date of birth.

Address (address): The user’s physical address.

Phone Number (phone_number): The user’s contact phone number.

Custom claims. Additional custom claims can be included based on the specific requirements of the application or system. These claims can capture any additional user-specific data needed for authentication, authorization, or personalized services.

The specific set of claims and their names may vary depending on the chosen decentralized identity framework, token format or application context. The claims included in the token should align with the requirements of your application and the information needed for secure and reliable user authentication and authorization.

When designing and implementing the claims in decentralized identity tokens, consider privacy considerations and the principle of data minimization. Only include the necessary information required for the operation of your application, adhering to relevant data protection regulations and best practices.

How to Extract Claims from Tokens in Go APIs

To extract claims from decentralized identity tokens in Go APIs, follow this guide:

Parse and Verify the Token.

Parse and verify the token using the jwt.Parse() function from the library. Ensure that the token is valid and has a valid signature. Here’s an example:

Extract Claims.

Once the token is validated, you can extract the claims from the token’s payload. Claims are typically stored as key-value pairs in the jwt.MapClaims type. Here’s an example:

In this example, we extract the sub (subject) claim as the userID. Make sure to handle type assertions appropriately based on the expected types of your claims.

Perform Claim Validation.

Validate the extracted claims based on your application’s requirements. Perform any necessary checks on the claims, such as role-based access control (RBAC), permissions, or any custom validation logic specific to your API. Here’s an example:

Customize the claim validations based on your application’s business logic and security requirements.

By following this guide, you can extract and validate claims from decentralized identity tokens in Go APIs. Adapt the code examples and validations to match the specific claims present in your tokens and the logic required for your API’s functionality and authorization rules.

How to Authenticate Users Based on Their Token Claims in Go

Using RBAC

The following is an example to illustrate the concept of authenticating users based on token claims using role-based access control (RBAC). Real-world usage may require additional security measures, error handling, and customization to meet your application’s specific requirements and security standards.

Always ensure that you adapt and thoroughly test such code in your own context before deploying it in a production environment.

In this example, the isAdminUser()function checks if the user has the admin role claim in their token. Adjust the logic based on your specific roles and claim names.

Permission-Based Authorization

The following serves as an example of permission-based authorization. In real-world applications, you should customize and extend it according to your specific permission structure and security requirements.

Ensure thorough testing and implement necessary security measures before deploying such code in a production environment.

In this example, the hasPermission() function checks if the user has the required permission in their token’s permissions claim. Customize the permission names and claim structure based on your application’s needs.

These code snippets demonstrate how to authenticate users based on their token claims using RBAC and permission-based authorization approaches. Customize the functions and claim validations according to your application’s specific claims, claim names and authorization logic.

Remember to validate the token’s authenticity, perform additional checks (such as expiration time), and implement any other necessary authorization checks specific to your application’s requirements and security policies.

How to Implement Authorization Check in Go APIs

Enforcing authorization checks in Go APIs based on user claims involves validating the user’s claims and ensuring they have the necessary permissions or roles to access specific resources or perform certain actions. Here’s a detailed explanation of how to implement authorization checks in Go APIs.

Extract and Validate Claims.

Using the token validation logic we discussed earlier, ensure that the user’s token is valid, has a valid signature and contains the necessary claims required for authorization.

Define Access Control Rules.

Define access control rules that specify the required permissions or roles for accessing different API resources or performing specific actions. These rules should be based on your application’s authorization requirements and business logic.

Implement Authorization Middleware.

Implement middleware functions that perform authorization checks before allowing access to protected resources. Middleware functions are executed before each API request and can enforce authorization rules consistently across multiple endpoints.

Here’s an example:

In this example, the AuthorizationMiddleware function takes the required permission as a parameter and checks if the user’s claims contain that permission. If the user doesn’t have the required permission, an unauthorized response is returned; otherwise, the request is passed to the next handler.

Apply Authorization Middleware to Protected Routes.

Apply the authorization middleware to the routes or endpoints that require specific authorization checks. Wrap the handlers for those routes with the authorization middleware. Here’s an example:

In this example, the /protected route is protected and requires the write_data permission. The YourProtectedHandler function contains the logic for handling the protected resource. The Authorization Middleware is applied to the /protected route, ensuring that only users with the write_data permission can access it.

How to Handle Various Authorization Scenarios

These examples demonstrate different authorization scenarios and how to handle them in Go APIs. Customize the code snippets based on your application’s specific requirements, roles, permissions or custom authorization logic. Ensure that you provide meaningful error responses for unauthorized access and grant access to authorized users only.


Scenario: Restrict access to a specific API endpoint to users with the admin role.

In this example, the /adminroute is protected and requires the admin role. Only users with the admin role in their token claims can access this endpoint.

Fine-Grained, Permission-Based Authorization

Scenario: Restrict access to a specific API endpoint based on a specific permission.

In this example, the /write-data route is protected and requires the write_data permission. Only users with the write_data permission in their token claims can access this endpoint.

Multilevel Authorization

Scenario: Restrict access to an API endpoint based on both the user’s role and specific permission.

In this example, the /admin-write route is protected and requires the admin role. Only users with the admin role in their token claims can access this endpoint.

Custom Authorization Logic

Scenario: Implement custom authorization logic based on specific business rules.

In this example, the /custom-auth route requires custom authorization logic. You can implement any specific authorization checks based on your business rules within the provided handler function.

Best Practices to Follow

When handling authorization logic in API handlers or middleware, follow best practices to ensure secure and effective authorization.

  • Use a centralized authorization mechanism. Implement a centralized authorization mechanism, such as middleware or a dedicated authorization service, to handle authorization logic. This promotes consistency, reusability and easier maintenance across multiple API endpoints.
  • Validate authorization early. Perform authorization checks as early as possible in the request processing pipeline. This ensures that unauthorized requests are rejected early, reducing unnecessary processing overhead.
  • Clearly define access-control rules. Define rules based on your application’s specific authorization needs. Document these rules and ensure they align with your overall security policies.
  • Leverage RBAC. Use RBAC principles to assign roles and permissions to users. Implement logic that checks the user’s role and required permissions to determine access rights. This promotes granular access control and easier management of user permissions.
  • Implement defense-in-depth. Apply multiple layers of security controls. Authorization checks should be complemented with other security measures, such as authentication, input validation and output encoding, to provide a comprehensive security posture.
  • Regularly review and update authorization logic. Be sure to accommodate changes in business requirements, roles, permissions and security policies. Perform periodic security audits to ensure the effectiveness and correctness of your authorization implementation.
  • Securely store and manage role and permission data. Ensure that only authorized administrators can modify or assign roles and permissions. Follow secure coding practices and protect sensitive data related to authorization.
  • Implement proper error handling. Return appropriate error responses when authorization fails, including clear messages that do not reveal sensitive information. Differentiate between authentication failures and authorization failures to provide meaningful feedback to clients.
  • Log authorization events. Events that should be logged, include successful and failed authorization attempts, to aid in audit trails, security monitoring, and the detection of suspicious activities or potential security breaches.
  • Test and validate authorization logic. Ensure That your authorization logic behaves as expected and effectively enforces access control. Implement unit tests and integration tests to cover different authorization scenarios.
Group Created with Sketch.
TNS owner Insight Partners is an investor in: Real.
THE NEW STACK UPDATE A newsletter digest of the week’s most important stories & analyses.