PHPackages                             zpm-packages/server-access - 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. zpm-packages/server-access

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

zpm-packages/server-access
==========================

Cross-platform PHP primitives for managing SSH-backed server access, users, keys, and permissions.

v1.0.0(1mo ago)084↓50%1MITPHPPHP ^8.2

Since May 6Pushed 1mo agoCompare

[ Source](https://github.com/zpm-packages/server-access-php)[ Packagist](https://packagist.org/packages/zpm-packages/server-access)[ RSS](/packages/zpm-packages-server-access/feed)WikiDiscussions main Synced 1w ago

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

ZPMPackages Server Access
=========================

[](#zpmpackages-server-access)

Cross-platform PHP primitives for managing SSH-backed server access, users, keys, permissions, and OS-level synchronization.

This package is **not** a full interactive SSH client library like phpseclib or OpenSSH bindings.
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
- execute management commands through configured manager credentials on local or remote hosts
- optionally sync repository state with OS-level config (e.g. `authorized_keys` – per OS provider)

In practice, it acts as a server-access management layer. It can target the current machine or a remote host by wrapping system commands with configured manager credentials, but it is not designed to be a general-purpose shell, terminal session, SFTP, or port-forwarding client.

The public PHP namespace is `ZPMPackages\SshManager\...`.

---

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

[](#installation)

```
composer require zpm-packages/server-access
```

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 ZPMPackages\SshManager\Repositories\InMemorySshRepository;

$repository = new InMemorySshRepository();
```

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

---

### 2. Create the Manager via Factory

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

```
use ZPMPackages\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 ZPMPackages\SshManager\Entities\SshEntryEntity;

/** @var \ZPMPackages\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 ZPMPackages\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 \ZPMPackages\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.

---

Framework Integrations
----------------------

[](#framework-integrations)

This package stays framework-agnostic on purpose. If you want container bindings, Laravel wrappers, Eloquent-backed repositories, sync commands, or a Filament admin UI, use the higher-level packages instead of duplicating that setup here.

- Laravel integration package: `zpm-packages/server-access-laravel`
- Filament admin package: `zpm-packages/server-access-filament`

Recommended wrapper structure in an application:

- bind `ZPMPackages\SshManager\Contracts\SshRepositoryContract` in your app or package
- resolve the manager through a wrapper or provider around `SshManagerFactory`
- keep app-specific database models, policies, and UI concerns outside this core package

See the package READMEs for those layers:

- Laravel wrapper: `../laravel-ssh-management/README.md`
- Filament wrapper: `../filament-ssh-management/README.md`

---

Notes
-----

[](#notes)

- All providers support the core entry management flow, while OS-level behavior depends on the active provider.
- When creating entries, SSH keys are automatically generated on the system.
- All code and comments are kept framework-agnostic. You can build Laravel, Symfony, or custom application layers on top of this package.
- Higher-level container bindings, persistence wrappers, and admin UI integrations belong in the Laravel and Filament packages, not in this core package.

###  Health Score

42

—

FairBetter than 88% of packages

Maintenance93

Actively maintained with recent releases

Popularity13

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity46

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

35d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/211412089?v=4)[ZPM Labs](/maintainers/zpmlabs)[@ZPMLabs](https://github.com/ZPMLabs)

---

Top Contributors

[![sasaorasanin](https://avatars.githubusercontent.com/u/100382372?v=4)](https://github.com/sasaorasanin "sasaorasanin (3 commits)")

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/zpm-packages-server-access/health.svg)

```
[![Health](https://phpackages.com/badges/zpm-packages-server-access/health.svg)](https://phpackages.com/packages/zpm-packages-server-access)
```

###  Alternatives

[mage-os/module-page-builder-template-import-export

PageBuilder template import/export module

1912.0k](/packages/mage-os-module-page-builder-template-import-export)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
