PHPackages                             artisan-build/scalpels - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. artisan-build/scalpels

ActiveLibrary

artisan-build/scalpels
======================

Laravel Composer package for Scalpels API integration

0695↑20%PHPCI passing

Since Jun 11Pushed 4mo ago2 watchersCompare

[ Source](https://github.com/artisan-build/scalpels)[ Packagist](https://packagist.org/packages/artisan-build/scalpels)[ RSS](/packages/artisan-build-scalpels/feed)WikiDiscussions main Synced 1mo ago

READMEChangelogDependenciesVersions (2)Used By (0)

Scalpels Laravel Package
========================

[](#scalpels-laravel-package)

A Laravel-first Composer package that provides a unified CLI interface and SDK for interacting with Scalpels tools, enabling developers to authenticate with account tokens for local development, generate service tokens for deployed environments, and consume tool APIs through a consistent, well-documented interface with automatic token rotation.

Installation
------------

[](#installation)

Install the package via Composer:

```
composer require artisan-build/scalpels
```

The package will auto-register its service provider and commands via Laravel's package discovery.

Quick Start
-----------

[](#quick-start)

### 1. Initialize Your Project

[](#1-initialize-your-project)

Configure your project with Scalpels URL and project ID:

```
php artisan scalpels:install --url=https://myteam.scalpels.app --project={uuid}
```

This command:

- Writes `SCALPELS_URL` and `SCALPELS_PROJECT` to both `.env` and `.env.example`
- Prepares your project for authentication

### 2. Authenticate

[](#2-authenticate)

Authenticate with your personal account credentials:

```
php artisan scalpels:auth
```

You'll be prompted for:

- Email address
- Password
- Two-factor authentication code (if enabled)

The command stores your account token in `~/.scalpels/default.json` for reuse across projects.

### 3. Start Using Scalpels Tools

[](#3-start-using-scalpels-tools)

Once authenticated, you can use tool-specific commands:

```
# Example: Pull environment variables (Environmental tool)
php artisan environmental:pull

# Example: Upload file (ALF tool)
php artisan alf:upload path/to/file.txt
```

Command Reference
-----------------

[](#command-reference)

### Core Commands

[](#core-commands)

#### `scalpels:install`

[](#scalpelsinstall)

Initialize Scalpels configuration in your project.

**Options:**

- `--url` (required): Scalpels API URL (e.g., `https://myteam.scalpels.app`)
- `--project` (required): Project UUID from Scalpels portal

**Example:**

```
php artisan scalpels:install \
    --url=https://myteam.scalpels.app \
    --project=550e8400-e29b-41d4-a716-446655440000
```

---

#### `scalpels:auth`

[](#scalpelsauth)

Authenticate with Scalpels using account credentials.

**Options:**

- `--name` (optional, default: `default`): Account name for token storage
- `--expires-in-days` (optional): Number of days until token expires

**Examples:**

Basic authentication:

```
php artisan scalpels:auth
```

Named account (for working with multiple clients):

```
php artisan scalpels:auth --name=client-two
```

With expiration:

```
php artisan scalpels:auth --expires-in-days=30
```

**Notes:**

- Account tokens are stored in `~/.scalpels/{name}.json`
- Tokens are reusable across all your projects
- File permissions are set to `0600` (owner read/write only)
- Two-factor authentication is required if enabled on your account

---

#### `scalpels:switch-account`

[](#scalpelsswitch-account)

Switch between stored account tokens.

**Arguments:**

- `account` (optional): Account name to switch to (prompts if not provided)

**Examples:**

Interactive menu:

```
php artisan scalpels:switch-account
```

Direct switch:

```
php artisan scalpels:switch-account client-two
```

**Notes:**

- Lists all stored accounts if no argument provided
- Shows account expiration dates
- Updates `~/.scalpels/current` symlink

---

#### `scalpels:generate-service-token`

[](#scalpelsgenerate-service-token)

Generate a service token for deployed environments.

**Arguments:**

- `environment` (required): Environment name (e.g., `production`, `staging`)
- `type` (required): Environment type - one of:
    - `production` - Production environment
    - `staging` - Staging environment
    - `preview` - Preview/review environment
    - `development` - Development environment
    - `testing` - Testing/CI environment

**Options:**

- `--name` (optional): Custom name for the service token

**Example:**

```
php artisan scalpels:generate-service-token production production
```

With custom name:

```
php artisan scalpels:generate-service-token staging staging --name="Staging v2"
```

**Output:**

```
Service token created successfully!

Environment: production
Type: production
Token: svc_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Webhook Secret: whsec_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

⚠ Store these credentials securely! They will not be shown again.

Add these to your deployment environment variables:
  SCALPELS_SERVICE_TOKEN=svc_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  SCALPELS_WEBHOOK_SECRET=whsec_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

```

**Notes:**

- Service tokens are NOT stored locally - you must add them to your deployment configuration
- Service tokens authenticate without user interaction
- Automatic rotation is supported (see Token Rotation section)

---

Service Token Generation Workflow
---------------------------------

[](#service-token-generation-workflow)

### Step-by-Step Guide

[](#step-by-step-guide)

1. **Authenticate locally** (if not already authenticated):

    ```
    php artisan scalpels:auth
    ```
2. **Generate service token** for your environment:

    ```
    php artisan scalpels:generate-service-token production production
    ```
3. **Copy the output** tokens to your clipboard
4. **Add to deployment** environment variables:

    - `SCALPELS_SERVICE_TOKEN` - The service token
    - `SCALPELS_WEBHOOK_SECRET` - The webhook secret (for webhook verification)
5. **Deploy your application**

The package SDK will automatically detect the service token and use it for API requests.

### Environment Types

[](#environment-types)

Choose the appropriate type for your deployment:

- **production**: Live production environment serving customers
- **staging**: Pre-production environment for testing
- **preview**: Temporary preview environments for pull requests
- **development**: Development servers accessible by team
- **testing**: CI/CD runners and automated testing environments

### Token Priority

[](#token-priority)

The SDK resolves tokens with the following priority:

1. **Service Token** (`SCALPELS_SERVICE_TOKEN` in `.env`)
2. **Account Token** (from `~/.scalpels/current` or specified account)
3. **None** (throws `AuthenticationException`)

This means service tokens always take precedence in deployed environments.

---

Webhook Setup
-------------

[](#webhook-setup)

### Registering Webhook Routes

[](#registering-webhook-routes)

Tool modules can register webhook endpoints in `routes/scalpels.php`:

```
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\ScalpelsWebhookController;
use ArtisanBuild\Scalpels\Middleware\VerifyWebhookSignature;

Route::prefix('webhooks/scalpels')
    ->middleware(['web', VerifyWebhookSignature::class])
    ->group(function () {
        Route::post('/environmental', [ScalpelsWebhookController::class, 'environmental']);
        Route::post('/alf', [ScalpelsWebhookController::class, 'alf']);
        Route::post('/glimpse', [ScalpelsWebhookController::class, 'glimpse']);
    });
```

### Webhook Signature Verification

[](#webhook-signature-verification)

All webhook requests are automatically verified using HMAC-SHA256 signatures:

1. Scalpels sends webhook with `X-Scalpels-Signature` header
2. Middleware computes HMAC-SHA256 hash of request body using your `SCALPELS_WEBHOOK_SECRET`
3. Middleware compares signatures using constant-time comparison
4. Request proceeds only if signatures match

**Security Notes:**

- Signatures use `hash_equals()` for constant-time comparison (prevents timing attacks)
- Invalid or missing signatures return `401 Unauthorized`
- Missing webhook secret configuration returns `500 Internal Server Error`

### Example Webhook Controller

[](#example-webhook-controller)

```
