PHPackages                             zpmlabs/ssh-manager - 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. [Utility &amp; Helpers](/categories/utility)
4. /
5. zpmlabs/ssh-manager

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

zpmlabs/ssh-manager
===================

OS-aware SSH configuration management package for PHP.

v1.0.0(6mo ago)00MITPHPPHP ^8.2

Since Nov 18Pushed 6mo ago1 watchersCompare

[ Source](https://github.com/zpm-packages/php-ssh-management)[ Packagist](https://packagist.org/packages/zpmlabs/ssh-manager)[ RSS](/packages/zpmlabs-ssh-manager/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (1)Dependencies (1)Versions (2)Used By (0)

ZPMLabs SSH Manager
===================

[](#zpmlabs-ssh-manager)

Simple, OS-aware SSH configuration manager for PHP.

This package **does not** act as an SSH client.
Its purpose is to:

- keep a structured list of SSH entries (users + keys + permissions) via a repository
- scan the current OS for SSH users and keys
- generate SSH key pairs for system users
- optionally sync repository state with OS-level config (e.g. `authorized_keys` – per OS provider)

---

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

[](#installation)

```
composer require zpmlabs/ssh-manager
```

Requires **PHP 8.2+**.

---

Basic Concepts
--------------

[](#basic-concepts)

- `SshEntryEntity`
    Represents one SSH entry (user + key paths + groups + permissions).
- `SshRepositoryContract`
    Abstraction for storing entries (in memory, JSON, DB …).
- `SshManagerContract`
    High-level API for:

    - listing entries
    - create / update / delete
    - scanning system users / keys
    - generating key pairs for system users
- `SshManagerFactory`
    Creates an OS-specific `SshManagerContract` implementation (Linux / Windows / macOS / Android).

---

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

[](#quick-start)

### 1. Create a Repository

[](#1-create-a-repository)

For testing and simple usage there is an in-memory implementation:

```
use ZPMLabs\SshManager\Repositories\InMemorySshRepository;

$repository = new InMemorySshRepository();
```

Later, you can replace this with your own implementation of `ZPMLabs\SshManager\Contracts\SshRepositoryContract` (e.g. DB / JSON file).

---

### 2. Create the Manager via Factory

[](#2-create-the-manager-via-factory)

```
use ZPMLabs\SshManager\Factories\SshManagerFactory;

// Detect OS automatically and create a manager for it:
$manager = SshManagerFactory::make($repository);
```

`SshManagerFactory` internally uses `SystemDetectorService` + `OperatingSystem` enum to choose the correct provider:

- Linux → `LinuxSshManagerProvider`
- Windows → `WindowsSshManagerProvider`
- macOS → `MacOsSshManagerProvider`
- Android → `AndroidSshManagerProvider`

---

Listing Entries
---------------

[](#listing-entries)

There are **two** ways to list entries:

1. From your **repository** (`listEntries`) – what *your app* stores.
2. From the **actual OS** (`scanSystemUsers`) – what the OS currently has.

### 1) List all stored entries (from repository)

[](#1-list-all-stored-entries-from-repository)

```
use ZPMLabs\SshManager\Entities\SshEntryEntity;

/** @var \ZPMLabs\SshManager\Contracts\SshManagerContract $manager */

// All entries, regardless of owner:
$entries = $manager->listEntries();

foreach ($entries as $entry) {
    /** @var SshEntryEntity $entry */
    echo $entry->getId() . PHP_EOL;
    echo 'User: ' . $entry->getUsername() . PHP_EOL;
    echo 'Home: ' . $entry->getHomeDirectory() . PHP_EOL;
    echo 'Public key path: ' . $entry->getPublicKeyPath() . PHP_EOL;
    echo 'Groups: ' . implode(', ', $entry->getGroups()) . PHP_EOL;
    echo str_repeat('-', 40) . PHP_EOL;
}
```

### 2) List entries for a specific owner (app-level user)

[](#2-list-entries-for-a-specific-owner-app-level-user)

```
$ownerId = 'user-123';

$entriesForOwner = $manager->listEntries($ownerId);
```

### 3) Scan system users / keys (OS-level, read-only)

[](#3-scan-system-users--keys-os-level-read-only)

```
$systemEntries = $manager->scanSystemUsers();

foreach ($systemEntries as $entry) {
    echo $entry->getUsername() . PHP_EOL;
    echo 'Home: ' . $entry->getHomeDirectory() . PHP_EOL;
    echo 'Public key path: ' . $entry->getPublicKeyPath() . PHP_EOL;
    echo 'Groups: ' . implode(', ', $entry->getGroups()) . PHP_EOL;
    echo str_repeat('=', 40) . PHP_EOL;
}
```

> `scanSystemUsers()` does **not** modify your repository.
> It just inspects the current OS state (for Linux provider it reads `/etc/passwd` and `~/.ssh`).

---

Creating Entries
----------------

[](#creating-entries)

You can create entries manually and store them in the repository via the manager.

```
use ZPMLabs\SshManager\Entities\SshEntryEntity;

$entry = new SshEntryEntity(
    id: 'entry-1',
    username: 'deploy',
    name: 'Deploy key',
    homeDirectory: '/home/deploy',
    publicKeyPath: '/home/deploy/.ssh/id_ed25519.pub',
    privateKeyPath: '/home/deploy/.ssh/id_ed25519',
    publicKey: null,          // optional – can be filled with file contents
    comment: 'Deployment key',
    groups: ['deploy', 'www-data'],
    ownerId: 'user-123',
    permissions: [],          // app-level permissions (see SshPermissionEntity)
);

// This writes to repository and triggers OS sync (if provider implements it).
$created = $manager->createEntry($entry);

// $created is the same entity, potentially modified by repository implementation.
```

---

Updating Entries
----------------

[](#updating-entries)

To update an existing entry:

```
/** @var \ZPMLabs\SshManager\Entities\SshEntryEntity|null $existing */
$existing = $manager->findEntry('entry-1');

if ($existing !== null) {
    $updatedEntry = new SshEntryEntity(
        id: $existing->getId(),
        username: $existing->getUsername(),
        name: 'Updated deploy key',
        homeDirectory: $existing->getHomeDirectory(),
        publicKeyPath: $existing->getPublicKeyPath(),
        privateKeyPath: $existing->getPrivateKeyPath(),
        publicKey: $existing->getPublicKey(),
        comment: 'Updated comment',
        groups: $existing->getGroups(),
        ownerId: $existing->getOwnerId(),
        permissions: $existing->getPermissions(),
    );

    $saved = $manager->updateEntry($updatedEntry);
}
```

`updateEntry()`:

- persists the updated entity in the repository
- calls `sync()` on the provider (if implemented), so OS config can be refreshed.

---

Deleting Entries
----------------

[](#deleting-entries)

To delete by ID:

```
$manager->deleteEntry('entry-1');
```

This:

1. Removes the entry from the repository.
2. Calls `sync()` on the provider, so OS-level configuration can be adjusted.

---

Generating SSH Key Pair for a System User
-----------------------------------------

[](#generating-ssh-key-pair-for-a-system-user)

On Linux, `LinuxSshManagerProvider` provides a real implementation using `ssh-keygen`. On other OS providers it is currently a TODO (they throw a `RuntimeException`).

```
// This will:
// 1) Resolve the system user's home dir.
// 2) Create ~/.ssh if it doesn't exist.
// 3) Run ssh-keygen and create files (e.g. id_ed25519 and id_ed25519.pub).
// 4) Create a SshEntryEntity for this key.
// 5) Store it in the repository.
// 6) Call sync() on the provider.
$newEntry = $manager->generateKeyPairForUser(
    systemUsername: 'deploy',
    label: 'deploy@my-server',  // comment in the key
    keyType: 'ed25519',         // or 'rsa'
    bits: null                  // for rsa you can pass e.g. 4096
);

echo $newEntry->getUsername() . PHP_EOL;
echo $newEntry->getPublicKeyPath() . PHP_EOL;
echo $newEntry->getPrivateKeyPath() . PHP_EOL;
```

---

Finding a Single Entry
----------------------

[](#finding-a-single-entry)

```
$entry = $manager->findEntry('entry-1');

if ($entry !== null) {
    echo $entry->getUsername() . PHP_EOL;
}
```

---

Extending the Package
---------------------

[](#extending-the-package)

You can extend the package in several ways:

- Implement your own `SshRepositoryContract`:
    - JSON file repository
    - Database-backed repository (e.g. Doctrine / Eloquent / custom)
- Implement OS-specific sync logic in providers:
    - generate `authorized_keys` files
    - update custom SSH config templates per entry
- Add additional providers for specific environments or containers.

---

Laravel Integration
-------------------

[](#laravel-integration)

This package works seamlessly with Laravel. Here's how to integrate it:

### Installation

[](#installation-1)

```
composer require zpmlabs/ssh-manager
```

### Service Provider Registration

[](#service-provider-registration)

Create a service provider to bind the SSH manager in Laravel's service container:

```
