
Security News
Attackers Are Hunting High-Impact Node.js Maintainers in a Coordinated Social Engineering Campaign
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.
@iamjs/koa
Advanced tools
This package contains middleware for integrating the authorization library into a Koa application.
@iamjs/koa
The @iamjs/koa package provides Koa middleware for the iamjs library, enabling seamless integration of role-based access control (RBAC) into your Koa applications. This middleware simplifies the process of managing permissions and authorizing requests based on user roles in a Koa environment.
To use @iamjs/koa, you need to install both the core library and the Koa middleware:
npm install @iamjs/core @iamjs/koa
# or
yarn add @iamjs/core @iamjs/koa
# or
pnpm add @iamjs/core @iamjs/koa
# or
bun add @iamjs/core @iamjs/koa
Here's a basic example of how to use the @iamjs/koa middleware for authorization:
import Koa from 'koa';
import Router from 'koa-router';
import { Role, Schema } from '@iamjs/core';
import { KoaRoleManager } from '@iamjs/koa';
const app = new Koa();
const router = new Router();
// Define a role
const userRole = new Role({
name: 'user',
config: {
posts: {
base: 'crudl',
custom: {
publish: true
}
},
comments: {
base: 'crud-'
}
}
});
// Create a schema with roles
const schema = new Schema({
roles: { user: userRole }
});
// Initialize the KoaRoleManager
const roleManager = new KoaRoleManager({
schema,
async onError(_err, ctx, next) {
ctx.status = 403;
ctx.body = { error: 'Access denied' };
await next();
},
async onSuccess(ctx, next) {
await next();
}
});
// Use the middleware to protect a route
router.get('/posts',
roleManager.check({
resources: 'posts',
actions: ['read', 'list'],
role: 'user'
}),
async (ctx) => {
ctx.body = { message: 'Posts retrieved successfully' };
}
);
app.use(router.routes()).use(router.allowedMethods());
app.listen(3000, () => {
console.log('Server running on http://localhost:3000');
});
In this example, we define a user role with specific permissions for posts and comments resources. The KoaRoleManager is then used to check if the user has the required permissions to access the /posts route.
For more complex scenarios, you can dynamically construct roles based on request data:
import Koa from 'koa';
import Router from 'koa-router';
import { Role, Schema } from '@iamjs/core';
import { KoaRoleManager } from '@iamjs/koa';
// ... (previous role and schema setup)
const app = new Koa();
const router = new Router();
// Middleware to attach user permissions to the context
app.use(async (ctx, next) => {
// In a real app, you'd fetch this from a database or JWT
ctx.state.userPermissions = userRole.toObject();
await next();
});
// Initialize the KoaRoleManager
const roleManager = new KoaRoleManager({
schema,
async onError(_err, ctx, next) {
ctx.status = 403;
ctx.body = { error: 'Access denied' };
await next();
}
});
router.get('/posts',
roleManager.check({
resources: 'posts',
actions: ['read', 'list'],
strict: true,
construct: true,
data: async (ctx) => ctx.state.userPermissions
}),
async (ctx) => {
ctx.body = { message: 'Posts retrieved successfully' };
}
);
app.use(router.routes()).use(router.allowedMethods());
This approach allows you to construct the role dynamically based on the user's actual permissions, which could be stored in a database or included in a JWT.
You can customize how the middleware handles successful and failed authorization attempts:
const roleManager = new KoaRoleManager({
schema,
async onError(err, ctx, next) {
console.error('Authorization failed:', err);
ctx.status = 403;
ctx.body = {
error: 'Access denied',
details: err.message
};
await next();
},
async onSuccess(ctx, next) {
console.log('Authorization successful for user:', ctx.state.userId);
await next();
}
});
These handlers give you fine-grained control over the response sent to the client and allow for custom logging or other actions.
The @iamjs/koa package provides strong TypeScript support. You can use generics to specify the types of your context object:
import Koa, { Context } from 'koa';
import Router from 'koa-router';
interface CustomContext extends Context {
state: {
userId: string;
userPermissions: object;
};
}
const roleManager = new KoaRoleManager({
schema,
async onSuccess<CustomContext>(ctx, next) {
console.log('Authorized user:', ctx.state.userId);
await next();
},
async onError<CustomContext>(err, ctx, next) {
console.error(`User ${ctx.state.userId} unauthorized:`, err);
ctx.status = 403;
ctx.body = { error: 'Access denied' };
await next();
}
});
router.get('/posts',
roleManager.check<CustomContext>({
resources: 'posts',
actions: ['read'],
role: 'user'
}),
async (ctx: CustomContext) => {
ctx.body = { message: `Posts retrieved for user ${ctx.state.userId}` };
}
);
This ensures type safety throughout your application, reducing the likelihood of runtime errors.
The KoaRoleManager allows you to log user activity, which can be useful for auditing and monitoring:
const roleManager = new KoaRoleManager({
schema,
async onError(_err, ctx, next) {
ctx.status = 403;
ctx.body = { error: 'Access denied' };
await next();
},
async onActivity(data) {
console.log('User activity:', data);
// In a real application, you might want to save this to a database
await saveActivityLog(data);
}
});
The onActivity handler receives an object with the following properties:
| Property | Description |
|---|---|
| actions | The action(s) that were authorized |
| resources | The resource(s) that were accessed |
| role | The role used for authorization |
| success | Whether the authorization was successful |
| ctx | The Koa context object (for additional context) |
constructor(options: KoaRoleManagerOptions)check(options: CheckOptions): Koa.Middlewareschema: Schema - The iamjs Schema containing role definitionsonError?: (err: Error, ctx: Koa.Context, next: Koa.Next) => Promise<void>onSuccess?: (ctx: Koa.Context, next: Koa.Next) => Promise<void>onActivity?: (data: ActivityData) => Promise<void> | voidresources: string | string[] - The resource(s) being accessedactions: string[] - The action(s) being performedrole?: string - The role to check against (if not using construct)strict?: boolean - Whether to require all specified permissionsconstruct?: boolean - Whether to construct the role dynamicallydata?: (ctx: Koa.Context) => Promise<object> | object - Function to retrieve role data (if construct is true)Use Environment-Specific Schemas: Create different schemas for different environments (development, staging, production) to manage permissions effectively across your deployment pipeline.
Implement Role Hierarchies: Utilize role inheritance to create a hierarchy, reducing duplication and simplifying management.
Granular Permissions: Define permissions at a granular level for fine-tuned access control.
Cache Role Data: For improved performance, consider caching role data, especially if you're constructing roles dynamically.
Audit Logs: Implement comprehensive logging using the onActivity handler to maintain an audit trail of all authorization decisions.
Error Handling: Provide clear, informative error messages in your onError handler to aid in debugging and improve user experience.
Regular Reviews: Periodically review and update your role definitions and permissions to ensure they align with your application's evolving security requirements.
check() matches the role defined in your schema.data function in dynamic role construction.We welcome contributions to @iamjs/koa! If you'd like to contribute, please:
Please see our Contributing Guide for more detailed information.
@iamjs/koa is released under the MIT License. See the LICENSE file for more details.
FAQs
This package contains middleware for integrating the authorization library into a Koa application.
The npm package @iamjs/koa receives a total of 17 weekly downloads. As such, @iamjs/koa popularity was classified as not popular.
We found that @iamjs/koa demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.