or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

authentication.mdcli-commands.mdconfiguration.mderrors.mdformatters.mdindex.mdmodels.mdprogrammatic.mdscanning.md

authentication.mddocs/

0

# Authentication System

1

2

Safety CLI provides a comprehensive authentication system for accessing the Safety platform services. The system supports multiple authentication methods including OAuth2 token-based authentication and API key authentication.

3

4

## Core Authentication Architecture

5

6

### Authentication Models { .api }

7

8

**Import Statements:**

9

10

```python

11

from safety.auth.models import Auth, Organization, XAPIKeyAuth

12

from safety.auth.utils import SafetyAuthSession

13

from safety.auth.cli_utils import (

14

auth_options, proxy_options,

15

build_client_session, inject_session

16

)

17

from safety_schemas.models import Stage

18

```

19

20

#### Organization Model { .api }

21

22

**Description**: Represents a Safety platform organization for multi-tenant authentication.

23

24

```python

25

@dataclass

26

class Organization:

27

id: str # Unique organization identifier

28

name: str # Organization display name

29

30

def to_dict(self) -> Dict[str, Any]:

31

"""

32

Convert organization to dictionary format.

33

34

Returns:

35

Dict[str, Any]: Organization data as dictionary

36

"""

37

```

38

39

**Example Usage:**

40

41

```python

42

from safety.auth.models import Organization

43

44

# Create organization instance

45

org = Organization(id="12345", name="My Company")

46

org_dict = org.to_dict()

47

# Output: {"id": "12345", "name": "My Company"}

48

```

49

50

#### Auth Model { .api }

51

52

**Description**: Central authentication state container managing credentials, client sessions, and user information.

53

54

```python

55

@dataclass

56

class Auth:

57

org: Optional[Organization] # Associated organization

58

keys: Any # OAuth keys and certificates

59

client: Any # HTTP client session

60

code_verifier: str # OAuth2 PKCE code verifier

61

client_id: str # OAuth2 client identifier

62

stage: Optional[Stage] = Stage.development # Environment stage

63

email: Optional[str] = None # User email address

64

name: Optional[str] = None # User display name

65

email_verified: bool = False # Email verification status

66

```

67

68

**Methods:**

69

70

```python

71

def is_valid(self) -> bool:

72

"""

73

Validate current authentication state.

74

75

Returns:

76

bool: True if authentication is valid and active

77

"""

78

79

def refresh_from(self, info: Dict[str, Any]) -> None:

80

"""

81

Update authentication state from user information.

82

83

Args:

84

info (Dict[str, Any]): User profile information from OAuth provider

85

"""

86

87

def get_auth_method(self) -> str:

88

"""

89

Get current authentication method being used.

90

91

Returns:

92

str: Authentication method ("API Key", "Token", or "None")

93

"""

94

```

95

96

**Example Usage:**

97

98

```python

99

from safety.auth.models import Auth, Organization

100

from safety_schemas.models import Stage

101

102

# Create auth instance

103

auth = Auth(

104

org=Organization(id="123", name="My Org"),

105

keys={},

106

client=None,

107

code_verifier="abc123",

108

client_id="safety-cli",

109

stage=Stage.PRODUCTION,

110

email="user@company.com",

111

name="John Doe",

112

email_verified=True

113

)

114

115

# Check authentication validity

116

if auth.is_valid():

117

print(f"Authenticated as {auth.name} using {auth.get_auth_method()}")

118

```

119

120

### Authentication Session Management { .api }

121

122

#### SafetyAuthSession Class { .api }

123

124

**Description**: Extended OAuth2Session with Safety-specific authentication handling and API integration.

125

126

```python

127

class SafetyAuthSession(OAuth2Session):

128

def __init__(self, *args: Any, **kwargs: Any) -> None:

129

"""

130

Initialize Safety authentication session.

131

132

Args:

133

*args: Positional arguments for OAuth2Session

134

**kwargs: Keyword arguments for OAuth2Session

135

"""

136

137

# Authentication state properties

138

proxy_required: bool # Require proxy for requests

139

proxy_timeout: Optional[int] # Proxy timeout in seconds

140

api_key: Optional[str] # API key for authentication

141

```

142

143

**Authentication Methods:**

144

145

```python

146

def get_credential(self) -> Optional[str]:

147

"""

148

Get current authentication credential (API key or token).

149

150

Returns:

151

Optional[str]: Current credential or None if not authenticated

152

"""

153

154

def is_using_auth_credentials(self) -> bool:

155

"""

156

Check if session is configured with authentication credentials.

157

158

Note: This checks configuration, not validity of credentials.

159

160

Returns:

161

bool: True if credentials are configured

162

"""

163

164

def get_authentication_type(self) -> AuthenticationType:

165

"""

166

Determine the type of authentication being used.

167

168

Returns:

169

AuthenticationType: Current authentication type (api_key, token, or none)

170

"""

171

```

172

173

**HTTP Request Handling:**

174

175

```python

176

def request(

177

self,

178

method: str, # HTTP method (GET, POST, etc.)

179

url: str, # Request URL

180

withhold_token: bool = False, # Skip token authentication

181

auth: Optional[Tuple] = None, # Custom authentication

182

bearer: bool = True, # Use bearer token format

183

**kwargs: Any # Additional request parameters

184

) -> requests.Response:

185

"""

186

Make authenticated HTTP request with automatic credential handling.

187

188

Automatically adds appropriate authentication headers:

189

- X-Api-Key header for API key authentication

190

- Authorization Bearer header for token authentication

191

- Safety CLI metadata headers

192

193

Args:

194

method: HTTP method to use

195

url: Target URL for request

196

withhold_token: Skip automatic token authentication

197

auth: Custom authentication tuple

198

bearer: Use bearer token format

199

**kwargs: Additional parameters (headers, timeout, etc.)

200

201

Returns:

202

requests.Response: HTTP response object

203

204

Raises:

205

RequestTimeoutError: If request times out

206

NetworkConnectionError: If network connection fails

207

ServerError: If server returns error status

208

"""

209

```

210

211

### Authentication Types { .api }

212

213

```python

214

from safety.scan.util import AuthenticationType

215

216

class AuthenticationType(Enum):

217

NONE = "none" # No authentication

218

API_KEY = "api_key" # API key authentication

219

TOKEN = "token" # OAuth2 token authentication

220

```

221

222

### API Key Authentication { .api }

223

224

#### XAPIKeyAuth Class { .api }

225

226

**Description**: API key authentication handler for requests.

227

228

```python

229

class XAPIKeyAuth(BaseOAuth):

230

def __init__(self, api_key: str) -> None:

231

"""

232

Initialize API key authentication.

233

234

Args:

235

api_key (str): Safety platform API key

236

"""

237

238

def __call__(self, request: Any) -> Any:

239

"""

240

Add API key to request headers.

241

242

Args:

243

request: HTTP request object to modify

244

245

Returns:

246

Any: Modified request with X-API-Key header

247

"""

248

```

249

250

**Example Usage:**

251

252

```python

253

from safety.auth.models import XAPIKeyAuth

254

import requests

255

256

# Create API key authenticator

257

auth = XAPIKeyAuth("sk-12345abcdef")

258

259

# Use with requests

260

response = requests.get(

261

"https://api.safetycli.com/scan",

262

auth=auth

263

)

264

```

265

266

## Authentication Commands Integration

267

268

### CLI Authentication Decorators { .api }

269

270

**Description**: Decorators for integrating authentication into CLI commands.

271

272

```python

273

from safety.auth.cli_utils import auth_options, proxy_options, inject_session

274

275

@auth_options

276

@proxy_options

277

def my_command(ctx, ...):

278

"""Command with authentication support."""

279

# Authentication automatically injected into ctx.obj.auth

280

session = ctx.obj.auth.client

281

```

282

283

#### auth_options Decorator { .api }

284

285

**Description**: Adds authentication-related command line options.

286

287

**Added Options:**

288

289

```bash

290

--key TEXT # API key for authentication

291

--auth-org-id TEXT # Organization ID override

292

--auth-stage {development,staging,production} # Environment stage

293

```

294

295

#### proxy_options Decorator { .api }

296

297

**Description**: Adds proxy configuration options for corporate environments.

298

299

**Added Options:**

300

301

```bash

302

--proxy-protocol {http,https} # Proxy protocol

303

--proxy-host TEXT # Proxy hostname

304

--proxy-port INTEGER # Proxy port number

305

--proxy-timeout INTEGER # Proxy timeout in seconds

306

```

307

308

#### inject_session Decorator { .api }

309

310

**Description**: Injects authenticated session into command context.

311

312

**Usage Pattern:**

313

314

```python

315

@inject_session

316

def authenticated_command(ctx):

317

"""Command with automatic session injection."""

318

# Access authenticated session

319

session: SafetyAuthSession = ctx.obj.auth.client

320

321

# Make authenticated requests

322

response = session.get("https://api.safetycli.com/user/profile")

323

```

324

325

### Session Building { .api }

326

327

#### build_client_session Function { .api }

328

329

**Description**: Factory function for creating authenticated client sessions.

330

331

```python

332

def build_client_session(

333

api_key: Optional[str] = None, # API key override

334

proxy_protocol: Optional[str] = None, # Proxy protocol

335

proxy_host: Optional[str] = None, # Proxy hostname

336

proxy_port: Optional[int] = None, # Proxy port

337

proxy_timeout: Optional[int] = None, # Proxy timeout

338

organization: Optional[Organization] = None, # Target organization

339

stage: Optional[Stage] = None # Environment stage

340

) -> SafetyAuthSession:

341

"""

342

Build authenticated client session with specified configuration.

343

344

Args:

345

api_key: API key for authentication (overrides stored credentials)

346

proxy_protocol: HTTP/HTTPS proxy protocol

347

proxy_host: Proxy server hostname

348

proxy_port: Proxy server port number

349

proxy_timeout: Timeout for proxy connections

350

organization: Target organization for multi-tenant access

351

stage: Environment stage for configuration

352

353

Returns:

354

SafetyAuthSession: Configured authenticated session

355

356

Raises:

357

InvalidCredentialError: If provided credentials are invalid

358

NetworkConnectionError: If proxy configuration is invalid

359

"""

360

```

361

362

**Example Usage:**

363

364

```python

365

from safety.auth.cli_utils import build_client_session

366

from safety.auth.models import Organization

367

from safety_schemas.models import Stage

368

369

# Build session with API key

370

session = build_client_session(

371

api_key="sk-12345abcdef",

372

organization=Organization(id="123", name="My Org"),

373

stage=Stage.PRODUCTION

374

)

375

376

# Build session with proxy

377

session = build_client_session(

378

proxy_protocol="https",

379

proxy_host="proxy.company.com",

380

proxy_port=8080,

381

proxy_timeout=30

382

)

383

```

384

385

## Platform API Integration

386

387

### Core API Endpoints { .api }

388

389

The SafetyAuthSession provides methods for interacting with Safety platform APIs:

390

391

```python

392

# User and organization management

393

session.get_user_info() -> Dict[str, Any] # Get user profile

394

session.get_organizations() -> List[Organization] # List organizations

395

396

# Project and scan management

397

session.create_project(name: str, org_id: str) -> Dict # Create project

398

session.upload_requirements(payload: Dict) -> Response # Upload scan data

399

session.download_policy(

400

project_id: str,

401

stage: Stage,

402

branch: Optional[str]

403

) -> Optional[Dict] # Download policy

404

405

# Vulnerability data access

406

session.get_vulnerabilities(packages: List) -> List # Get vulnerability data

407

session.get_licenses(packages: List) -> Dict # Get license data

408

```

409

410

### Authentication Flow Integration {.api }

411

412

```python

413

from safety.auth.main import get_authorization_data, handle_authentication_flow

414

415

def get_authorization_data(

416

client: SafetyAuthSession, # Client session

417

code_verifier: str, # PKCE code verifier

418

organization: Optional[Organization] = None, # Target organization

419

headless: bool = False # Headless mode flag

420

) -> Tuple[str, Dict]:

421

"""

422

Generate OAuth2 authorization URL and initial state.

423

424

Args:

425

client: Authenticated client session

426

code_verifier: PKCE code verifier for security

427

organization: Target organization for login

428

headless: Enable headless mode for CI/CD

429

430

Returns:

431

Tuple[str, Dict]: Authorization URL and initial state data

432

"""

433

434

def handle_authentication_flow(

435

ctx, # Command context

436

authorization_url: str, # OAuth authorization URL

437

initial_state: Dict, # Initial authentication state

438

headless: bool = False # Headless mode flag

439

) -> bool:

440

"""

441

Handle complete OAuth2 authentication flow.

442

443

Args:

444

ctx: Typer command context

445

authorization_url: URL for user authentication

446

initial_state: Authentication state data

447

headless: Use headless authentication mode

448

449

Returns:

450

bool: True if authentication successful

451

452

Raises:

453

InvalidCredentialError: If authentication fails

454

NetworkConnectionError: If unable to connect to auth server

455

"""

456

```

457

458

## Error Handling { .api }

459

460

### Authentication Exceptions { .api }

461

462

```python

463

from safety.errors import (

464

InvalidCredentialError,

465

NetworkConnectionError,

466

RequestTimeoutError,

467

ServerError,

468

TooManyRequestsError

469

)

470

471

# Authentication-specific errors

472

class InvalidCredentialError(SafetyError):

473

"""Raised when provided credentials are invalid or expired."""

474

475

class NetworkConnectionError(SafetyError):

476

"""Raised when unable to establish network connection."""

477

478

class RequestTimeoutError(SafetyError):

479

"""Raised when requests exceed configured timeout."""

480

```

481

482

### Error Handling Patterns { .api }

483

484

```python

485

from safety.auth.utils import SafetyAuthSession

486

from safety.errors import InvalidCredentialError

487

488

try:

489

session = SafetyAuthSession()

490

session.api_key = "sk-invalid-key"

491

492

response = session.get("https://api.safetycli.com/user/profile")

493

response.raise_for_status()

494

495

except InvalidCredentialError as e:

496

print(f"Authentication failed: {e}")

497

except NetworkConnectionError as e:

498

print(f"Network error: {e}")

499

except RequestTimeoutError as e:

500

print(f"Request timed out: {e}")

501

```

502

503

## Configuration and Environment

504

505

### Environment Variables { .api }

506

507

Authentication behavior can be configured via environment variables:

508

509

```bash

510

# API authentication

511

SAFETY_API_KEY # Default API key

512

SAFETY_API_BASE_URL # API base URL override

513

514

# Proxy configuration

515

SAFETY_PROXY_HOST # Proxy hostname

516

SAFETY_PROXY_PORT # Proxy port

517

SAFETY_PROXY_PROTOCOL # Proxy protocol (http/https)

518

SAFETY_PROXY_TIMEOUT # Proxy timeout in seconds

519

520

# OAuth configuration

521

SAFETY_AUTH_SERVER_URL # Authentication server URL

522

SAFETY_CLIENT_ID # OAuth2 client ID

523

```

524

525

### Configuration Files { .api }

526

527

Authentication settings are stored in Safety configuration directories:

528

529

```bash

530

# User configuration (Linux/macOS)

531

~/.config/safety/auth.json

532

533

# System configuration

534

/etc/safety/auth.json

535

536

# Windows user configuration

537

%APPDATA%\safety\auth.json

538

```

539

540

## Usage Examples

541

542

### Basic Authentication Setup

543

544

```python

545

from safety.auth.cli_utils import build_client_session

546

from safety.auth.models import Organization

547

from safety_schemas.models import Stage

548

549

# API Key Authentication

550

session = build_client_session(api_key="sk-12345abcdef")

551

552

# OAuth Token Authentication (requires prior login)

553

session = build_client_session()

554

555

# Organization-specific Authentication

556

org = Organization(id="123", name="My Company")

557

session = build_client_session(

558

organization=org,

559

stage=Stage.PRODUCTION

560

)

561

```

562

563

### Corporate Proxy Configuration

564

565

```python

566

# Configure session with corporate proxy

567

session = build_client_session(

568

api_key="sk-12345abcdef",

569

proxy_protocol="https",

570

proxy_host="proxy.company.com",

571

proxy_port=8080,

572

proxy_timeout=60

573

)

574

575

# Make authenticated request through proxy

576

response = session.get("https://api.safetycli.com/scan")

577

```

578

579

### Multi-Organization Access

580

581

```python

582

from safety.auth.models import Auth, Organization

583

584

# List available organizations

585

session = build_client_session()

586

orgs_response = session.get("/organizations")

587

organizations = [

588

Organization(id=org["id"], name=org["name"])

589

for org in orgs_response.json()

590

]

591

592

# Switch to specific organization

593

target_org = organizations[0]

594

org_session = build_client_session(organization=target_org)

595

```

596

597

### Authentication State Management

598

599

```python

600

from safety.auth.models import Auth

601

602

# Check authentication status

603

auth = Auth(...) # Initialized from context

604

605

if auth.is_valid():

606

method = auth.get_auth_method()

607

print(f"Authenticated via {method}")

608

609

if auth.org:

610

print(f"Organization: {auth.org.name}")

611

612

if auth.email:

613

print(f"User: {auth.name} ({auth.email})")

614

else:

615

print("Not authenticated")

616

```

617

618

This comprehensive authentication documentation covers all aspects of Safety CLI's authentication system, enabling developers to implement secure and robust integrations with the Safety platform.