Users, Roles and Access Keys in Lioran S3
Object storage security is not just “put a password in .env”.
The current Lioran S3 V1 Pre-Alpha includes human users, roles, password management, and programmatic access keys.
Lioran S3 is built by Lioran Developer Solutions (LDS) under Lioran Group, led by Founder & CTO Swaraj Puppalwar.
Current roles
The server exposes three primary roles:
admin
readwrite
readonly
Use the least privileged role that satisfies the workload.
Create a user
const user =
await client.users.create({
username: "developer",
password:
"InitialSecurePassword123!",
role: "readwrite",
});
console.log(user);
List users
const users =
await client.users.list();
console.log(users);
Change role
await client.users.setRole(
"developer",
"readonly"
);
Disable
await client.users.disable(
"developer"
);
Enable again:
await client.users.enable(
"developer"
);
Admin password reset
await client.users.resetPassword(
"developer",
"NewPassword456!",
{
mustChangePassword: true,
}
);
Self-service password change
await client.users.changePassword(
"OldPassword123!",
"NewPassword456!"
);
Delete
await client.users.delete(
"developer"
);
Bootstrap credential rotation
Development defaults are convenient.
Production defaults are landmines wearing slippers.
Lioran S3 treats the initial administrator password as bootstrap state and supports mandatory password rotation.
Production configuration should always use explicitly configured credentials.
Programmatic access keys
Long-running services should not depend on a human password.
Create a key:
const key =
await client.accessKeys.create({
name: "ci-pipeline",
owner: "developer",
expiresAt:
new Date(
Date.now() +
90 * 86400 * 1000
),
});
The secret is returned when the key is created.
Store it immediately.
console.log(key.key_id);
console.log(key.secret_key);
Do not expect to retrieve the original secret later.
Authenticate using an access key
import {
BastionClient,
} from "@liorans3/driver";
const ciClient =
new BastionClient({
accessKey:
process.env.LIORAN_ACCESS_KEY!,
secretKey:
process.env.LIORAN_SECRET_KEY!,
host:
"storage.example.com",
isTls: true,
});
List keys
const keys =
await client.accessKeys.list();
Rotate
const rotated =
await client.accessKeys.rotate(
key.key_id
);
console.log(
rotated.secret_key
);
Rotation invalidates the old secret.
Revoke
await client.accessKeys.delete(
key.key_id
);
CLI workflows
Users:
liorans3 user ls
liorans3 user get alice
liorans3 user create alice --role readwrite
liorans3 user update alice --role readonly
liorans3 user disable alice
liorans3 user enable alice
liorans3 user passwd
liorans3 user reset-password alice
liorans3 user rm alice
Keys:
liorans3 key ls
liorans3 key create "CI/CD Deployment Key" --expires-days 90
liorans3 key rotate bk_example
liorans3 key revoke bk_example
Credential redaction
The driver and CLI are designed to mask credentials in common error and diagnostic surfaces.
For example, a safe representation should look conceptually like:
bastion://admin:***@storage.example.com
That does not eliminate the need to protect logs.
It reduces accidental leakage.
Practical model
For a small production-style setup:
admin
|
├── infrastructure administration
|
├── service user: application-api
| └── access key
|
└── readonly user: analytics
Keep human and machine credentials separate.
Rotation policy
A reasonable operational baseline:
- rotate bootstrap credentials immediately
- expire temporary access keys
- use separate keys per service
- revoke keys when a service is decommissioned
- do not reuse one secret across environments
- keep production and staging identities separate
- never commit secrets into Git
Current scope
V1 roles are intentionally simpler than a full IAM policy language.
Fine-grained IAM-style policy controls are part of the broader roadmap.
For pre-alpha, the security work is focused on strong primitives that can be exercised and tested before adding a giant authorization grammar.
Top comments (0)