@navirondynamics/accord 1.1.0 β 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +161 -81
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,22 +1,64 @@
|
|
|
1
1
|
# Accord
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
<p align="center">
|
|
4
|
+
<a href="https://www.npmjs.com/package/@navirondynamics/accord">
|
|
5
|
+
<img src="https://img.shields.io/npm/v/@navirondynamics/accord.svg" alt="npm version" />
|
|
6
|
+
</a>
|
|
7
|
+
<a href="https://www.npmjs.com/package/@navirondynamics/accord">
|
|
8
|
+
<img src="https://img.shields.io/npm/dm/@navirondynamics/accord.svg" alt="npm downloads" />
|
|
9
|
+
</a>
|
|
10
|
+
<a href="https://github.com/bsen-alt/Accord">
|
|
11
|
+
<img src="https://img.shields.io/github/license/bsen-alt/Accord" alt="license" />
|
|
12
|
+
</a>
|
|
13
|
+
</p>
|
|
4
14
|
|
|
5
|
-
|
|
15
|
+
Accord is a **policy-first identity and access engine for Node.js**.
|
|
6
16
|
|
|
7
|
-
|
|
17
|
+
It treats access not as scattered application logic, but as a formal agreement between identities, systems, and resources - evaluated through declarative, versioned policies.
|
|
8
18
|
|
|
9
|
-
|
|
19
|
+
**New in v1.1:** Observability, YAML configuration, hot reload, and native NestJS support.
|
|
10
20
|
|
|
11
|
-
|
|
12
|
-
- Roles defined in another.
|
|
13
|
-
- Access logic scattered across codebases.
|
|
21
|
+
---
|
|
14
22
|
|
|
15
|
-
|
|
23
|
+
## Table of Contents
|
|
16
24
|
|
|
17
|
-
-
|
|
18
|
-
-
|
|
19
|
-
-
|
|
25
|
+
- [Why Accord](#-why-accord)
|
|
26
|
+
- [Key Features](#key-features)
|
|
27
|
+
- [Installation](#-installation)
|
|
28
|
+
- [Quick Start](#-quick-start-v11)
|
|
29
|
+
- [Framework Integration](#-framework-integration)
|
|
30
|
+
- [CLI Tool](#-cli-tool)
|
|
31
|
+
- [Documentation](#-documentation)
|
|
32
|
+
- [Roadmap](#-roadmap)
|
|
33
|
+
- [Contributing](#-contributing)
|
|
34
|
+
- [License](#-license)
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## π Why Accord?
|
|
39
|
+
|
|
40
|
+
Modern authorization is fragmented:
|
|
41
|
+
|
|
42
|
+
- Authentication in one service
|
|
43
|
+
- Roles in another
|
|
44
|
+
- Access logic scattered across microservices
|
|
45
|
+
|
|
46
|
+
Accord centralizes authorization into a single **governance layer**, acting as the _System of Record_ for access control across your platform.
|
|
47
|
+
|
|
48
|
+
Instead of embedding authorization logic throughout your codebase, Accord externalizes it into auditable, inspectable, and versioned policy definitions.
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## Key Features
|
|
53
|
+
|
|
54
|
+
- π **Observability** β Built-in audit logging (console & file)
|
|
55
|
+
- π **Policy as Code** β JSON and YAML configuration support
|
|
56
|
+
- π‘οΈ **Reliability** β Zod-based schema validation to prevent invalid policies
|
|
57
|
+
- π **Zero-Downtime Updates** β Hot reload policies without restarting services
|
|
58
|
+
- π§© **Framework Adapters** β Express, NestJS, and Fastify integrations
|
|
59
|
+
- π¦ **CLI Tooling** β Validate and simulate access decisions locally
|
|
60
|
+
|
|
61
|
+
---
|
|
20
62
|
|
|
21
63
|
## π¦ Installation
|
|
22
64
|
|
|
@@ -24,89 +66,93 @@ Modern authorization is often fragmented:
|
|
|
24
66
|
npm install @navirondynamics/accord
|
|
25
67
|
```
|
|
26
68
|
|
|
27
|
-
|
|
69
|
+
---
|
|
28
70
|
|
|
29
|
-
|
|
71
|
+
## π οΈ Quick Start (v1.1)
|
|
30
72
|
|
|
31
|
-
|
|
73
|
+
### 1. Define Policies (YAML supported)
|
|
32
74
|
|
|
33
|
-
|
|
75
|
+
Create `config/policies.yaml`:
|
|
34
76
|
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
"resource": { "type": "booking" }
|
|
47
|
-
}
|
|
48
|
-
]
|
|
77
|
+
```yaml
|
|
78
|
+
- id: 'admin-delete'
|
|
79
|
+
version: '1.1'
|
|
80
|
+
effect: 'allow'
|
|
81
|
+
subject:
|
|
82
|
+
type: 'user'
|
|
83
|
+
attributes:
|
|
84
|
+
role: 'admin'
|
|
85
|
+
action: ['delete']
|
|
86
|
+
resource:
|
|
87
|
+
type: 'booking'
|
|
49
88
|
```
|
|
50
89
|
|
|
51
|
-
|
|
90
|
+
---
|
|
52
91
|
|
|
53
|
-
|
|
54
|
-
[
|
|
55
|
-
{
|
|
56
|
-
"id": "alice",
|
|
57
|
-
"type": "user",
|
|
58
|
-
"status": "active",
|
|
59
|
-
"attributes": { "role": "admin" }
|
|
60
|
-
}
|
|
61
|
-
]
|
|
62
|
-
```
|
|
63
|
-
|
|
64
|
-
### 2. Use in Your Code
|
|
92
|
+
### 2. Initialize Accord
|
|
65
93
|
|
|
66
94
|
```javascript
|
|
67
|
-
const { Accord } = require('@navirondynamics/accord');
|
|
95
|
+
const { Accord, ConsoleAuditLogger } = require('@navirondynamics/accord');
|
|
68
96
|
|
|
69
|
-
// 1. Initialize the Engine
|
|
70
97
|
const accord = new Accord({
|
|
71
|
-
policyPath: './config/policies.
|
|
98
|
+
policyPath: './config/policies.yaml',
|
|
72
99
|
identityPath: './config/identities.json',
|
|
100
|
+
logger: new ConsoleAuditLogger(),
|
|
73
101
|
});
|
|
102
|
+
```
|
|
74
103
|
|
|
75
|
-
|
|
76
|
-
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
### 3. Check Access
|
|
107
|
+
|
|
108
|
+
```javascript
|
|
109
|
+
async function deleteUser(userId) {
|
|
77
110
|
const decision = await accord.check(userId, 'delete', {
|
|
78
|
-
type: '
|
|
79
|
-
id:
|
|
111
|
+
type: 'user',
|
|
112
|
+
id: userId,
|
|
80
113
|
});
|
|
81
114
|
|
|
82
|
-
// 3. Enforce Decision
|
|
83
115
|
if (decision.decision === 'allow') {
|
|
84
|
-
console.log('
|
|
85
|
-
// Perform
|
|
116
|
+
console.log('Permission Granted');
|
|
117
|
+
// Perform deletion...
|
|
86
118
|
} else {
|
|
87
119
|
console.log('Access Denied:', decision.reason);
|
|
88
120
|
}
|
|
89
121
|
}
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
## π‘οΈ Framework Integration
|
|
127
|
+
|
|
128
|
+
### NestJS
|
|
129
|
+
|
|
130
|
+
```typescript
|
|
131
|
+
import { AccordGuard } from '@navirondynamics/accord/adapters/nest';
|
|
90
132
|
|
|
91
|
-
|
|
133
|
+
@Controller('bookings')
|
|
134
|
+
export class BookingController {
|
|
135
|
+
@UseGuards(
|
|
136
|
+
new AccordGuard({
|
|
137
|
+
accordInstance: accord,
|
|
138
|
+
action: 'delete',
|
|
139
|
+
resourceType: 'booking',
|
|
140
|
+
})
|
|
141
|
+
)
|
|
142
|
+
@Delete(':id')
|
|
143
|
+
deleteBooking(@Param('id') id: string) {
|
|
144
|
+
// Only authorized users reach here
|
|
145
|
+
}
|
|
146
|
+
}
|
|
92
147
|
```
|
|
93
148
|
|
|
94
|
-
|
|
149
|
+
---
|
|
95
150
|
|
|
96
|
-
|
|
151
|
+
### Express
|
|
97
152
|
|
|
98
153
|
```javascript
|
|
99
|
-
const express = require('express');
|
|
100
|
-
const { Accord } = require('@navirondynamics/accord');
|
|
101
154
|
const { protect } = require('@navirondynamics/accord/adapters/express');
|
|
102
155
|
|
|
103
|
-
const app = express();
|
|
104
|
-
const accord = new Accord({
|
|
105
|
-
policyPath: './config/policies.json',
|
|
106
|
-
identityPath: './config/identities.json',
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
// Protect this route
|
|
110
156
|
app.delete(
|
|
111
157
|
'/bookings/:id',
|
|
112
158
|
protect({
|
|
@@ -115,36 +161,70 @@ app.delete(
|
|
|
115
161
|
resourceType: 'booking',
|
|
116
162
|
}),
|
|
117
163
|
(req, res) => {
|
|
118
|
-
|
|
119
|
-
res.send('Booking deleted');
|
|
164
|
+
res.send('Deleted');
|
|
120
165
|
}
|
|
121
166
|
);
|
|
122
|
-
|
|
123
|
-
app.listen(3000);
|
|
124
167
|
```
|
|
125
168
|
|
|
126
|
-
|
|
169
|
+
Fastify support and advanced usage are available in the adapters documentation.
|
|
170
|
+
|
|
171
|
+
---
|
|
127
172
|
|
|
128
|
-
|
|
173
|
+
## π§ CLI Tool
|
|
129
174
|
|
|
130
|
-
|
|
175
|
+
Validate policies or simulate access decisions directly from your terminal.
|
|
131
176
|
|
|
132
177
|
```bash
|
|
133
|
-
|
|
178
|
+
# Validate policy syntax
|
|
179
|
+
npx @navirondynamics/accord validate ./config/policies.yaml
|
|
180
|
+
|
|
181
|
+
# Test access logic
|
|
182
|
+
npx @navirondynamics/accord eval -i user_123 -a delete -r booking
|
|
134
183
|
```
|
|
135
184
|
|
|
136
|
-
|
|
185
|
+
---
|
|
137
186
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
187
|
+
## π Documentation
|
|
188
|
+
|
|
189
|
+
- **Getting Started** β Installation and core concepts
|
|
190
|
+
- **Configuration Guide** β Identities, policies, JSON vs YAML
|
|
191
|
+
- **Observability & Auditing** β Production logging setup
|
|
192
|
+
- **Framework Adapters** β Express, NestJS, Fastify usage
|
|
193
|
+
- **CLI Reference** β Full command list
|
|
194
|
+
|
|
195
|
+
---
|
|
196
|
+
|
|
197
|
+
## πΊοΈ Roadmap
|
|
198
|
+
|
|
199
|
+
Planned improvements:
|
|
200
|
+
|
|
201
|
+
- Policy versioning & rollback
|
|
202
|
+
- Database-backed policy storage
|
|
203
|
+
- Web-based policy editor
|
|
204
|
+
- Decision caching
|
|
205
|
+
- OpenTelemetry tracing
|
|
206
|
+
- Distributed policy synchronization
|
|
207
|
+
|
|
208
|
+
---
|
|
209
|
+
|
|
210
|
+
## π€ Contributing
|
|
211
|
+
|
|
212
|
+
Contributions are welcome.
|
|
213
|
+
|
|
214
|
+
1. Fork the repository
|
|
215
|
+
2. Create a feature branch
|
|
216
|
+
|
|
217
|
+
```bash
|
|
218
|
+
git checkout -b feature/my-feature
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
3. Commit your changes
|
|
222
|
+
4. Push to your fork
|
|
223
|
+
5. Open a Pull Request
|
|
141
224
|
|
|
142
|
-
|
|
225
|
+
Please ensure tests pass and documentation is updated.
|
|
143
226
|
|
|
144
|
-
|
|
145
|
-
- **Resource:** Represents what is being accessed.
|
|
146
|
-
- **Policy:** The agreement linking Identity, Action, and Resource. Supports RBAC (Roles) and ABAC (Attributes).
|
|
147
|
-
- **Decision:** The output (`allow`/`deny`) including a `reason` for auditing.
|
|
227
|
+
---
|
|
148
228
|
|
|
149
229
|
## π License
|
|
150
230
|
|