or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

authentication.mdauthorization.mdexceptions.mdindex.md

authorization.mddocs/

0

# Authorization Management

1

2

The authorization management components provide the core interfaces and implementations for controlling access to CDAP resources through role-based access control and privilege management.

3

4

## Core Authorization Interface

5

6

### Authorizer

7

8

The main interface that authorization extensions must implement to provide custom authorization logic.

9

10

```java { .api }

11

@Beta

12

interface Authorizer extends PrivilegesFetcher, PrivilegesManager, AuthorizationEnforcer {

13

/**

14

* Initialize the Authorizer with the provided context.

15

*/

16

void initialize(AuthorizationContext context) throws Exception;

17

18

/**

19

* Create a new role.

20

*/

21

void createRole(Role role) throws Exception;

22

23

/**

24

* Drop a role.

25

*/

26

void dropRole(Role role) throws Exception;

27

28

/**

29

* Add a role to the specified Principal.

30

*/

31

void addRoleToPrincipal(Role role, Principal principal) throws Exception;

32

33

/**

34

* Remove a role from the specified Principal.

35

*/

36

void removeRoleFromPrincipal(Role role, Principal principal) throws Exception;

37

38

/**

39

* List all roles for the specified Principal.

40

*/

41

Set<Role> listRoles(Principal principal) throws Exception;

42

43

/**

44

* List all available roles in the system.

45

*/

46

Set<Role> listAllRoles() throws Exception;

47

48

/**

49

* Cleanup method called when the authorizer is destroyed.

50

*/

51

void destroy() throws Exception;

52

}

53

```

54

55

### AuthorizationEnforcer

56

57

Interface for enforcing access control decisions.

58

59

```java { .api }

60

@Beta

61

interface AuthorizationEnforcer {

62

/**

63

* Enforce authorization for a single action.

64

*/

65

void enforce(EntityId entity, Principal principal, Action action) throws Exception;

66

67

/**

68

* Enforce authorization for multiple actions.

69

*/

70

void enforce(EntityId entity, Principal principal, Set<Action> actions) throws Exception;

71

72

/**

73

* Check which entities are visible to the principal.

74

*/

75

Set<? extends EntityId> isVisible(Set<? extends EntityId> entityIds, Principal principal) throws Exception;

76

}

77

```

78

79

### PrivilegesManager

80

81

Interface for managing privileges on entities.

82

83

```java { .api }

84

interface PrivilegesManager {

85

/**

86

* Grant privileges to a principal on an authorizable entity.

87

*/

88

void grant(Authorizable authorizable, Principal principal, Set<Action> actions) throws Exception;

89

90

/**

91

* Revoke specific privileges from a principal on an authorizable entity.

92

*/

93

void revoke(Authorizable authorizable, Principal principal, Set<Action> actions) throws Exception;

94

95

/**

96

* Revoke all privileges on an authorizable entity.

97

*/

98

void revoke(Authorizable authorizable) throws Exception;

99

100

/**

101

* List all privileges for a principal.

102

*/

103

Set<Privilege> listPrivileges(Principal principal) throws Exception;

104

}

105

```

106

107

### PrivilegesFetcher

108

109

Interface for retrieving privilege information.

110

111

```java { .api }

112

interface PrivilegesFetcher {

113

/**

114

* List all privileges for the specified principal.

115

*/

116

Set<Privilege> listPrivileges(Principal principal) throws Exception;

117

}

118

```

119

120

## Base Implementation Classes

121

122

### AbstractAuthorizer

123

124

Abstract base class providing default implementations for lifecycle methods.

125

126

```java { .api }

127

abstract class AbstractAuthorizer implements Authorizer {

128

protected static final Predicate<EntityId> ALLOW_ALL;

129

130

/**

131

* Default no-op initialization.

132

*/

133

void initialize(AuthorizationContext context) throws Exception;

134

135

/**

136

* Default no-op cleanup.

137

*/

138

void destroy() throws Exception;

139

140

/**

141

* Single-action enforcement that delegates to multi-action method.

142

*/

143

void enforce(EntityId entity, Principal principal, Action action) throws Exception;

144

}

145

```

146

147

### NoOpAuthorizer

148

149

No-operation implementation used when authorization is disabled.

150

151

```java { .api }

152

class NoOpAuthorizer extends AbstractAuthorizer {

153

void enforce(EntityId entity, Principal principal, Set<Action> actions) throws Exception;

154

Set<? extends EntityId> isVisible(Set<? extends EntityId> entityIds, Principal principal) throws Exception;

155

void grant(Authorizable authorizable, Principal principal, Set<Action> actions) throws Exception;

156

void revoke(Authorizable authorizable, Principal principal, Set<Action> actions) throws Exception;

157

void revoke(Authorizable authorizable) throws Exception;

158

void createRole(Role role);

159

void dropRole(Role role);

160

void addRoleToPrincipal(Role role, Principal principal);

161

void removeRoleFromPrincipal(Role role, Principal principal);

162

Set<Role> listRoles(Principal principal);

163

Set<Role> listAllRoles();

164

Set<Privilege> listPrivileges(Principal principal);

165

}

166

```

167

168

## Authorization Context

169

170

### AuthorizationContext

171

172

Context interface providing access to CDAP services for authorization extensions.

173

174

```java { .api }

175

interface AuthorizationContext extends DatasetContext, Admin, Transactional,

176

AuthenticationContext, SecureStore {

177

/**

178

* Get extension properties from cdap-site.xml with prefix

179

* security.authorization.extension.config.

180

*/

181

Properties getExtensionProperties();

182

183

// Messaging operations (all throw UnsupportedOperationException)

184

void createTopic(String topic) throws TopicAlreadyExistsException, IOException;

185

void createTopic(String topic, Map<String, String> properties) throws TopicAlreadyExistsException, IOException;

186

Map<String, String> getTopicProperties(String topic) throws TopicNotFoundException, IOException;

187

void updateTopic(String topic, Map<String, String> properties) throws TopicNotFoundException, IOException;

188

void deleteTopic(String topic) throws TopicNotFoundException, IOException;

189

}

190

```

191

192

## Usage Examples

193

194

### Custom Authorization Backend

195

196

```java

197

public class LdapAuthorizer extends AbstractAuthorizer {

198

private LdapConnection ldapConnection;

199

private String baseDn;

200

201

@Override

202

public void initialize(AuthorizationContext context) throws Exception {

203

Properties props = context.getExtensionProperties();

204

String ldapUrl = props.getProperty("ldap.url");

205

String bindDn = props.getProperty("ldap.bind.dn");

206

String bindPassword = props.getProperty("ldap.bind.password");

207

baseDn = props.getProperty("ldap.base.dn");

208

209

ldapConnection = new LdapConnection(ldapUrl, bindDn, bindPassword);

210

}

211

212

@Override

213

public void enforce(EntityId entity, Principal principal, Set<Action> actions)

214

throws Exception {

215

// Query LDAP to check if user has required permissions

216

String userDn = "uid=" + principal.getName() + "," + baseDn;

217

218

for (Action action : actions) {

219

if (!hasLdapPermission(userDn, entity, action)) {

220

throw new UnauthorizedException(principal, action, entity);

221

}

222

}

223

}

224

225

@Override

226

public void grant(Authorizable authorizable, Principal principal, Set<Action> actions)

227

throws Exception {

228

// Add LDAP group membership or attributes

229

String userDn = "uid=" + principal.getName() + "," + baseDn;

230

for (Action action : actions) {

231

String groupDn = buildPermissionGroupDn(authorizable, action);

232

ldapConnection.addUserToGroup(userDn, groupDn);

233

}

234

}

235

236

@Override

237

public Set<Role> listRoles(Principal principal) throws Exception {

238

// Query LDAP groups for user

239

String userDn = "uid=" + principal.getName() + "," + baseDn;

240

return ldapConnection.getUserGroups(userDn)

241

.stream()

242

.map(groupName -> new Role(groupName))

243

.collect(Collectors.toSet());

244

}

245

246

@Override

247

public void destroy() throws Exception {

248

if (ldapConnection != null) {

249

ldapConnection.close();

250

}

251

}

252

253

private boolean hasLdapPermission(String userDn, EntityId entity, Action action) {

254

// Implementation specific to your LDAP schema

255

return false;

256

}

257

258

private String buildPermissionGroupDn(Authorizable authorizable, Action action) {

259

// Build group DN based on your LDAP schema

260

return "cn=" + authorizable.toString() + "-" + action.name() + "," + baseDn;

261

}

262

}

263

```

264

265

### Role-Based Access Control

266

267

```java

268

public class SimpleRoleAuthorizer extends AbstractAuthorizer {

269

private Map<String, Set<Role>> userRoles = new HashMap<>();

270

private Map<Role, Set<Privilege>> rolePrivileges = new HashMap<>();

271

272

@Override

273

public void createRole(Role role) throws Exception {

274

if (rolePrivileges.containsKey(role)) {

275

throw new AlreadyExistsException(role);

276

}

277

rolePrivileges.put(role, new HashSet<>());

278

}

279

280

@Override

281

public void addRoleToPrincipal(Role role, Principal principal) throws Exception {

282

if (!rolePrivileges.containsKey(role)) {

283

throw new NotFoundException(role);

284

}

285

userRoles.computeIfAbsent(principal.getName(), k -> new HashSet<>()).add(role);

286

}

287

288

@Override

289

public void grant(Authorizable authorizable, Principal principal, Set<Action> actions)

290

throws Exception {

291

// If granting to a role, update role privileges

292

if (principal.getType() == PrincipalType.ROLE) {

293

Role role = new Role(principal.getName());

294

Set<Privilege> privileges = rolePrivileges.get(role);

295

if (privileges != null) {

296

for (Action action : actions) {

297

privileges.add(new Privilege(authorizable, action));

298

}

299

}

300

}

301

}

302

303

@Override

304

public void enforce(EntityId entity, Principal principal, Set<Action> actions)

305

throws Exception {

306

Set<Privilege> userPrivileges = getUserPrivileges(principal);

307

308

for (Action action : actions) {

309

boolean hasPermission = userPrivileges.stream()

310

.anyMatch(p -> p.getAction().equals(action) &&

311

entityMatches(p.getAuthorizable(), entity));

312

313

if (!hasPermission) {

314

throw new UnauthorizedException(principal, action, entity);

315

}

316

}

317

}

318

319

private Set<Privilege> getUserPrivileges(Principal principal) {

320

Set<Privilege> privileges = new HashSet<>();

321

Set<Role> roles = userRoles.get(principal.getName());

322

323

if (roles != null) {

324

for (Role role : roles) {

325

Set<Privilege> rolePrivs = rolePrivileges.get(role);

326

if (rolePrivs != null) {

327

privileges.addAll(rolePrivs);

328

}

329

}

330

}

331

332

return privileges;

333

}

334

335

private boolean entityMatches(Authorizable authorizable, EntityId entity) {

336

// Implementation-specific logic to match entities

337

return authorizable.toString().equals(entity.toString());

338

}

339

}