or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

context-management.mdengine-language-management.mdindex.mdjava-python-interop.mdsecurity-access-control.mdsource-management.mdvalue-operations.md

security-access-control.mddocs/

0

# Security and Access Control

1

2

Security and access control provide comprehensive protection mechanisms for Python code execution within Java applications. The framework offers multiple layers of security including host access policies, inter-language restrictions, I/O controls, and sandbox environments with varying trust levels.

3

4

## Capabilities

5

6

### Host Access Policies

7

8

Control how Python code can access Java objects and methods.

9

10

```java { .api }

11

/**

12

* Host access policy that requires explicit @Export annotations

13

*/

14

public static final HostAccess EXPLICIT;

15

16

/**

17

* Host access policy allowing unrestricted access to all host objects

18

*/

19

public static final HostAccess ALL;

20

21

/**

22

* Host access policy denying all host access

23

*/

24

public static final HostAccess NONE;

25

26

/**

27

* Host access policy for constrained sandbox environments

28

*/

29

public static final HostAccess CONSTRAINED;

30

31

/**

32

* Host access policy for isolated sandbox environments

33

*/

34

public static final HostAccess ISOLATED;

35

36

/**

37

* Host access policy for untrusted sandbox environments

38

*/

39

public static final HostAccess UNTRUSTED;

40

41

/**

42

* Creates a builder for custom host access policies

43

* @return HostAccess.Builder for configuration

44

*/

45

public static Builder newBuilder();

46

47

/**

48

* Creates a builder based on an existing policy

49

* @param prototype existing HostAccess to use as template

50

* @return HostAccess.Builder for configuration

51

*/

52

public static Builder newBuilder(HostAccess prototype);

53

```

54

55

**Usage Examples:**

56

57

```java

58

// Explicit access - requires @Export annotation

59

public class Calculator {

60

@HostAccess.Export

61

public int add(int a, int b) {

62

return a + b;

63

}

64

65

// Not accessible from Python without @Export

66

public int subtract(int a, int b) {

67

return a - b;

68

}

69

}

70

71

Context explicitContext = Context.newBuilder("python")

72

.allowHostAccess(HostAccess.EXPLICIT)

73

.build();

74

75

Calculator calc = new Calculator();

76

explicitContext.getPolyglotBindings().putMember("calculator", calc);

77

78

// Only add() is accessible

79

Value result1 = explicitContext.eval("python", "calculator.add(5, 3)"); // Works: 8

80

// Value result2 = explicitContext.eval("python", "calculator.subtract(5, 3)"); // Fails

81

82

// Unrestricted access

83

Context allAccessContext = Context.newBuilder("python")

84

.allowHostAccess(HostAccess.ALL)

85

.build();

86

87

allAccessContext.getPolyglotBindings().putMember("calculator", calc);

88

Value result3 = allAccessContext.eval("python", "calculator.subtract(10, 4)"); // Works: 6

89

90

// No host access

91

Context noAccessContext = Context.newBuilder("python")

92

.allowHostAccess(HostAccess.NONE)

93

.build();

94

95

// Cannot pass host objects or access Java functionality

96

// noAccessContext.getPolyglotBindings().putMember("calculator", calc); // Would fail

97

98

// Sandbox-specific policies

99

Context constrainedContext = Context.newBuilder("python")

100

.allowHostAccess(HostAccess.CONSTRAINED)

101

.sandbox(SandboxPolicy.CONSTRAINED)

102

.build();

103

```

104

105

### Custom Host Access Policies

106

107

Create fine-grained host access controls with custom rules.

108

109

```java { .api }

110

/**

111

* Builder for creating custom host access policies

112

*/

113

public static final class HostAccess.Builder {

114

/**

115

* Allows access to all public members of specified classes

116

* @param classes the classes to allow access to

117

* @return this builder

118

*/

119

public Builder allowAccessToAllClasses(Class<?>... classes);

120

121

/**

122

* Allows access to members annotated with @Export

123

* @param export true to allow exported members

124

* @return this builder

125

*/

126

public Builder allowAccessAnnotatedBy(Class<? extends Annotation> annotation);

127

128

/**

129

* Allows access to all public members

130

* @param allPublic true to allow all public access

131

* @return this builder

132

*/

133

public Builder allowAllPublicAccess(boolean allPublic);

134

135

/**

136

* Allows access to array elements

137

* @param arrayAccess true to allow array access

138

* @return this builder

139

*/

140

public Builder allowArrayAccess(boolean arrayAccess);

141

142

/**

143

* Allows access to List elements

144

* @param listAccess true to allow List access

145

* @return this builder

146

*/

147

public Builder allowListAccess(boolean listAccess);

148

149

/**

150

* Allows access to Map elements

151

* @param mapAccess true to allow Map access

152

* @return this builder

153

*/

154

public Builder allowMapAccess(boolean mapAccess);

155

156

/**

157

* Allows buffer access for binary data

158

* @param bufferAccess true to allow buffer access

159

* @return this builder

160

*/

161

public Builder allowBufferAccess(boolean bufferAccess);

162

163

/**

164

* Allows implementation of functional interfaces

165

* @param functionalInterface true to allow functional interfaces

166

* @return this builder

167

*/

168

public Builder allowImplementationsAnnotatedBy(Class<? extends Annotation> annotation);

169

170

/**

171

* Builds the configured host access policy

172

* @return new HostAccess instance

173

*/

174

public HostAccess build();

175

}

176

177

/**

178

* Annotation to mark methods/fields as accessible from guest languages

179

*/

180

@Retention(RetentionPolicy.RUNTIME)

181

@Target({ElementType.CONSTRUCTOR, ElementType.FIELD, ElementType.METHOD, ElementType.TYPE})

182

public @interface Export {

183

}

184

```

185

186

**Usage Examples:**

187

188

```java

189

// Custom policy allowing specific classes

190

HostAccess customPolicy = HostAccess.newBuilder()

191

.allowAccessToAllClasses(String.class, Integer.class, Double.class)

192

.allowArrayAccess(true)

193

.allowListAccess(true)

194

.allowMapAccess(true)

195

.build();

196

197

Context customContext = Context.newBuilder("python")

198

.allowHostAccess(customPolicy)

199

.build();

200

201

// Data transfer objects with selective access

202

public class UserData {

203

@HostAccess.Export

204

public String name;

205

206

@HostAccess.Export

207

public int age;

208

209

// Private - not accessible

210

private String socialSecurityNumber;

211

212

@HostAccess.Export

213

public String getDisplayName() {

214

return "User: " + name;

215

}

216

217

// Not exported - not accessible

218

public String getSSN() {

219

return socialSecurityNumber;

220

}

221

}

222

223

// Selective access policy

224

HostAccess selectivePolicy = HostAccess.newBuilder()

225

.allowAccessAnnotatedBy(HostAccess.Export.class)

226

.allowListAccess(true)

227

.build();

228

229

Context selectiveContext = Context.newBuilder("python")

230

.allowHostAccess(selectivePolicy)

231

.build();

232

233

UserData user = new UserData();

234

user.name = "Alice";

235

user.age = 30;

236

selectiveContext.getPolyglotBindings().putMember("user", user);

237

238

// Accessible

239

Value userName = selectiveContext.eval("python", "user.name"); // "Alice"

240

Value displayName = selectiveContext.eval("python", "user.getDisplayName()"); // "User: Alice"

241

242

// Not accessible - would throw exception

243

// Value ssn = selectiveContext.eval("python", "user.getSSN()");

244

```

245

246

### Polyglot Access Control

247

248

Control inter-language evaluation and data sharing between different guest languages.

249

250

```java { .api }

251

/**

252

* Policy denying all inter-language access

253

*/

254

public static final PolyglotAccess NONE;

255

256

/**

257

* Policy allowing full inter-language access

258

*/

259

public static final PolyglotAccess ALL;

260

261

/**

262

* Creates a builder for custom polyglot access policies

263

* @return PolyglotAccess.Builder for configuration

264

*/

265

public static Builder newBuilder();

266

267

/**

268

* Builder for creating custom polyglot access policies

269

*/

270

public static final class PolyglotAccess.Builder {

271

/**

272

* Allows the specified language to evaluate code in target languages

273

* @param language the source language

274

* @param targetLanguages the languages it can evaluate

275

* @return this builder

276

*/

277

public Builder allowEval(String language, String... targetLanguages);

278

279

/**

280

* Allows binding sharing between specified languages

281

* @param language the source language

282

* @param targetLanguages the languages it can share bindings with

283

* @return this builder

284

*/

285

public Builder allowBindingsAccess(String language, String... targetLanguages);

286

287

/**

288

* Builds the configured polyglot access policy

289

* @return new PolyglotAccess instance

290

*/

291

public PolyglotAccess build();

292

}

293

```

294

295

**Usage Examples:**

296

297

```java

298

// No inter-language access

299

Context isolatedContext = Context.newBuilder("python", "js")

300

.allowPolyglotAccess(PolyglotAccess.NONE)

301

.build();

302

303

// Python cannot evaluate JavaScript

304

// isolatedContext.eval("python", "polyglot.eval('js', '1 + 1')"); // Would fail

305

306

// Full inter-language access

307

Context polyglotContext = Context.newBuilder("python", "js")

308

.allowPolyglotAccess(PolyglotAccess.ALL)

309

.build();

310

311

// Python can evaluate JavaScript

312

Value jsResult = polyglotContext.eval("python", "polyglot.eval('js', '1 + 1')"); // 2

313

314

// Custom selective access

315

PolyglotAccess customPolyglotAccess = PolyglotAccess.newBuilder()

316

.allowEval("python", "js") // Python can eval JS

317

.allowBindingsAccess("python", "js") // Python can access JS bindings

318

.build();

319

320

Context selectivePolyglotContext = Context.newBuilder("python", "js")

321

.allowPolyglotAccess(customPolyglotAccess)

322

.build();

323

324

// Share data between languages

325

selectivePolyglotContext.eval("js", "globalThis.shared_value = 42;");

326

Value sharedValue = selectivePolyglotContext.eval("python",

327

"polyglot.eval('js', 'globalThis.shared_value')"); // 42

328

```

329

330

### Sandbox Policies

331

332

Define security levels with predefined sandbox configurations.

333

334

```java { .api }

335

/**

336

* Sandbox policy enumeration defining security levels

337

*/

338

public enum SandboxPolicy {

339

/**

340

* Fully trusted applications with no restrictions (default)

341

*/

342

TRUSTED,

343

344

/**

345

* Trusted but potentially buggy applications with basic protections

346

*/

347

CONSTRAINED,

348

349

/**

350

* Applications with potential security vulnerabilities requiring isolation

351

*/

352

ISOLATED,

353

354

/**

355

* Fully untrusted applications requiring maximum security

356

*/

357

UNTRUSTED

358

}

359

```

360

361

**Usage Examples:**

362

363

```java

364

// Trusted environment - no restrictions

365

Context trustedContext = Context.newBuilder("python")

366

.sandbox(SandboxPolicy.TRUSTED)

367

.allowHostAccess(HostAccess.ALL)

368

.allowIO(IOAccess.ALL)

369

.build();

370

371

// Full access to system resources

372

trustedContext.eval("python", """

373

import os

374

import subprocess

375

print(os.getcwd())

376

# Can access file system, network, etc.

377

""");

378

379

// Constrained environment - limited but functional

380

Context constrainedContext = Context.newBuilder("python")

381

.sandbox(SandboxPolicy.CONSTRAINED)

382

.allowHostAccess(HostAccess.CONSTRAINED)

383

.allowIO(IOAccess.newBuilder()

384

.allowHostFileAccess(Path.of("/app/data"))

385

.build())

386

.build();

387

388

// Limited file access, controlled host access

389

constrainedContext.eval("python", """

390

# Can read from /app/data directory

391

with open('/app/data/config.txt', 'r') as f:

392

config = f.read()

393

print(config)

394

""");

395

396

// Isolated environment - strong restrictions

397

Context isolatedContext = Context.newBuilder("python")

398

.sandbox(SandboxPolicy.ISOLATED)

399

.allowHostAccess(HostAccess.ISOLATED)

400

.allowIO(IOAccess.NONE)

401

.build();

402

403

// Very limited access

404

isolatedContext.eval("python", """

405

# Pure computation only

406

result = sum(range(100))

407

print(f"Sum: {result}")

408

# Cannot access files, network, or most host functionality

409

""");

410

411

// Untrusted environment - maximum security

412

Context untrustedContext = Context.newBuilder("python")

413

.sandbox(SandboxPolicy.UNTRUSTED)

414

.allowHostAccess(HostAccess.UNTRUSTED)

415

.allowIO(IOAccess.NONE)

416

.allowPolyglotAccess(PolyglotAccess.NONE)

417

.resourceLimits(ResourceLimits.newBuilder()

418

.statementLimit(10000, null)

419

.timeLimit(Duration.ofSeconds(5))

420

.build())

421

.build();

422

423

// Maximum restrictions with resource limits

424

untrustedContext.eval("python", """

425

# Only basic computation allowed

426

x = 42

427

y = x * 2

428

print(y) # 84

429

""");

430

```

431

432

### I/O Access Control

433

434

Control file system, network, and other I/O operations.

435

436

```java { .api }

437

/**

438

* I/O access policy denying all I/O operations

439

*/

440

public static final IOAccess NONE;

441

442

/**

443

* I/O access policy allowing full host I/O access

444

*/

445

public static final IOAccess ALL;

446

447

/**

448

* Creates a builder for custom I/O access policies

449

* @return IOAccess.Builder for configuration

450

*/

451

public static Builder newBuilder();

452

453

/**

454

* Creates a builder based on an existing I/O policy

455

* @param prototype existing IOAccess to use as template

456

* @return IOAccess.Builder for configuration

457

*/

458

public static Builder newBuilder(IOAccess prototype);

459

460

/**

461

* Builder for creating custom I/O access policies

462

*/

463

public static final class IOAccess.Builder {

464

/**

465

* Allows host file access to specified paths

466

* @param path the file path to allow access to

467

* @return this builder

468

*/

469

public Builder allowHostFileAccess(Path path);

470

471

/**

472

* Allows host socket access for network operations

473

* @param hostSocketAccess true to allow socket access

474

* @return this builder

475

*/

476

public Builder allowHostSocketAccess(boolean hostSocketAccess);

477

478

/**

479

* Sets a custom file system implementation

480

* @param fileSystem the FileSystem to use

481

* @return this builder

482

*/

483

public Builder fileSystem(FileSystem fileSystem);

484

485

/**

486

* Builds the configured I/O access policy

487

* @return new IOAccess instance

488

*/

489

public IOAccess build();

490

}

491

```

492

493

**Usage Examples:**

494

495

```java

496

// No I/O access

497

Context noIOContext = Context.newBuilder("python")

498

.allowIO(IOAccess.NONE)

499

.build();

500

501

// Cannot access files or network

502

// noIOContext.eval("python", "open('file.txt', 'r')"); // Would fail

503

504

// Full I/O access

505

Context fullIOContext = Context.newBuilder("python")

506

.allowIO(IOAccess.ALL)

507

.build();

508

509

// Can access any file or network resource

510

fullIOContext.eval("python", """

511

import urllib.request

512

with open('/tmp/test.txt', 'w') as f:

513

f.write('Hello, World!')

514

""");

515

516

// Custom I/O policy with restricted file access

517

IOAccess restrictedIO = IOAccess.newBuilder()

518

.allowHostFileAccess(Path.of("/app/data"))

519

.allowHostFileAccess(Path.of("/tmp"))

520

.allowHostSocketAccess(false) // No network access

521

.build();

522

523

Context restrictedContext = Context.newBuilder("python")

524

.allowIO(restrictedIO)

525

.build();

526

527

// Can only access specific directories

528

restrictedContext.eval("python", """

529

# Allowed

530

with open('/app/data/input.txt', 'r') as f:

531

data = f.read()

532

533

with open('/tmp/output.txt', 'w') as f:

534

f.write(data.upper())

535

536

# Not allowed - would fail

537

# with open('/etc/passwd', 'r') as f:

538

# content = f.read()

539

""");

540

541

// Virtual file system

542

FileSystem virtualFS = createVirtualFileSystem(); // Custom implementation

543

IOAccess virtualIO = IOAccess.newBuilder()

544

.fileSystem(virtualFS)

545

.build();

546

547

Context virtualContext = Context.newBuilder("python")

548

.allowIO(virtualIO)

549

.build();

550

551

// All file operations go through virtual file system

552

virtualContext.eval("python", """

553

# Uses virtual file system

554

with open('virtual_file.txt', 'w') as f:

555

f.write('This goes to virtual storage')

556

""");

557

```

558

559

### Resource Limits

560

561

Control resource usage including CPU time, memory, and statement execution limits.

562

563

```java { .api }

564

/**

565

* Builder for creating resource limit configurations

566

*/

567

public static final class ResourceLimits.Builder {

568

/**

569

* Sets a limit on the number of statements executed

570

* @param statementLimit maximum number of statements

571

* @param onLimit callback when limit is reached (optional)

572

* @return this builder

573

*/

574

public Builder statementLimit(long statementLimit, Consumer<ResourceLimitEvent> onLimit);

575

576

/**

577

* Sets a time limit for execution

578

* @param timeLimit maximum execution time

579

* @return this builder

580

*/

581

public Builder timeLimit(Duration timeLimit);

582

583

/**

584

* Builds the configured resource limits

585

* @return new ResourceLimits instance

586

*/

587

public ResourceLimits build();

588

}

589

590

/**

591

* Event fired when resource limits are reached

592

*/

593

public final class ResourceLimitEvent {

594

/**

595

* Gets the type of limit that was exceeded

596

* @return limit type description

597

*/

598

public String getLimitType();

599

600

/**

601

* Gets the current resource usage

602

* @return current usage value

603

*/

604

public long getCurrentUsage();

605

606

/**

607

* Gets the limit that was exceeded

608

* @return limit value

609

*/

610

public long getLimit();

611

}

612

```

613

614

**Usage Examples:**

615

616

```java

617

// Statement limit with callback

618

ResourceLimits statementLimits = ResourceLimits.newBuilder()

619

.statementLimit(1000, event -> {

620

System.out.println("Statement limit exceeded: " +

621

event.getCurrentUsage() + "/" + event.getLimit());

622

})

623

.build();

624

625

Context limitedContext = Context.newBuilder("python")

626

.resourceLimits(statementLimits)

627

.build();

628

629

try {

630

limitedContext.eval("python", """

631

# This will hit the statement limit

632

total = 0

633

for i in range(10000): # Too many iterations

634

total += i

635

print(total)

636

""");

637

} catch (PolyglotException e) {

638

if (e.isResourceExhausted()) {

639

System.out.println("Resource limit exceeded");

640

}

641

}

642

643

// Time limit

644

ResourceLimits timeLimits = ResourceLimits.newBuilder()

645

.timeLimit(Duration.ofSeconds(5))

646

.build();

647

648

Context timeContext = Context.newBuilder("python")

649

.resourceLimits(timeLimits)

650

.build();

651

652

try {

653

timeContext.eval("python", """

654

import time

655

# This will timeout

656

for i in range(1000000):

657

time.sleep(0.001) # Small delay adds up

658

""");

659

} catch (PolyglotException e) {

660

if (e.isResourceExhausted()) {

661

System.out.println("Time limit exceeded");

662

}

663

}

664

665

// Combined limits

666

ResourceLimits combinedLimits = ResourceLimits.newBuilder()

667

.statementLimit(5000, null)

668

.timeLimit(Duration.ofSeconds(10))

669

.build();

670

671

Context combinedContext = Context.newBuilder("python")

672

.resourceLimits(combinedLimits)

673

.sandbox(SandboxPolicy.CONSTRAINED)

674

.build();

675

676

// Reset limits if needed

677

combinedContext.resetLimits();

678

```

679

680

## Types

681

682

```java { .api }

683

/**

684

* Exception thrown when security policy violations occur

685

*/

686

public final class SecurityException extends PolyglotException {

687

/**

688

* Gets the security policy that was violated

689

* @return policy description

690

*/

691

public String getViolatedPolicy();

692

693

/**

694

* Gets the attempted operation that was blocked

695

* @return operation description

696

*/

697

public String getBlockedOperation();

698

}

699

700

/**

701

* Environment access control for process environment variables

702

*/

703

public final class EnvironmentAccess {

704

/**

705

* No access to environment variables

706

*/

707

public static final EnvironmentAccess NONE;

708

709

/**

710

* Full access to inherit environment variables

711

*/

712

public static final EnvironmentAccess INHERIT;

713

714

/**

715

* Creates custom environment access with specific variables

716

* @param allowedVariables map of allowed environment variables

717

* @return EnvironmentAccess instance

718

*/

719

public static EnvironmentAccess allowedVariables(Map<String, String> allowedVariables);

720

}

721

```