-
Notifications
You must be signed in to change notification settings - Fork 0
Closed
Description
📌 Parent Issue
#182 (Phase 3: Secret Sharing & Access Control)
🎯 Goal
Complete Phase 3 with integration tests, policy updates for file attachments, and documentation finalization.
📋 Implementation Tasks
1. Update SecretAttachmentPolicy
Location: app/Policies/SecretAttachmentPolicy.php
Current Issue: Policy only checks owner_id, ignoring shares.
Updates Needed:
-
view(User $user, SecretAttachment $attachment)- Check secret shares -
create(User $user, Secret $secret)- Check write+ permission -
delete(User $user, SecretAttachment $attachment)- Check write+ permission
Implementation:
public function view(User $user, SecretAttachment $attachment): bool
{
return $attachment->secret->userHasPermission($user, 'read');
}
public function create(User $user, Secret $secret): bool
{
return $secret->userHasPermission($user, 'write');
}
public function delete(User $user, SecretAttachment $attachment): bool
{
return $attachment->secret->userHasPermission($user, 'write');
}2. Integration Tests
Test Suites:
Secrets + Shares Integration
- User can view secret shared with read permission
- User can update secret shared with write permission
- User can delete secret shared with admin permission
- User with read permission cannot update secret
- User with write permission cannot delete secret
- Expired share does not grant access
- Revoking share immediately removes access
Secrets + Attachments + Shares Integration
- User with read share can view attachments
- User with read share can download attachments
- User with read share cannot upload attachments
- User with write share can upload attachments
- User with write share can delete attachments
- User without share cannot access attachments
Role-Based Shares Integration
- User with role receives permissions from role share
- User assigned to role can access shared secrets
- User removed from role loses access to role-shared secrets
- Multiple roles combine permissions correctly
Edge Cases
- Cascade delete: Deleting secret removes shares
- Cascade delete: Deleting secret removes attachments
- Cascade delete: Deleting user removes their shares
- Owner can always access secret even with no explicit share
- Sharing with self (user_id = owner_id) is allowed but redundant
Coverage Target: ≥80% for integration scenarios
3. API Documentation
Location: SecPal/contracts repository
Tasks:
- Update OpenAPI spec with Secret endpoints
- Update OpenAPI spec with SecretShare endpoints
- Add example requests/responses
- Document XOR constraint for shares
- Document permission hierarchy (admin > write > read)
Files to Update:
contracts/
├── openapi.yaml
├── paths/
│ ├── secrets.yaml (new)
│ └── secret-shares.yaml (new)
└── components/
└── schemas/
├── Secret.yaml (new)
└── SecretShare.yaml (new)
4. Documentation Updates
api/docs/:
- Update
docs/rbac-architecture.md- Add Secret Sharing section - Create
docs/guides/secret-sharing.md- User guide - Update
README.md- Add Secret Management to features list
Content for docs/guides/secret-sharing.md:
# Secret Sharing Guide
## Permission Levels
- **read**: View secret + download attachments
- **write**: read + update secret + upload/delete attachments
- **admin**: write + delete secret + manage shares
## Granting Access
### Share with User
POST /v1/secrets/{id}/shares
{
"user_id": "uuid",
"permission": "read",
"expires_at": "2026-01-01T00:00:00Z"
}
### Share with Role
POST /v1/secrets/{id}/shares
{
"role_id": 5,
"permission": "write"
}
## Revoking Access
DELETE /v1/secrets/{id}/shares/{share_id}5. CHANGELOG Update
Location: CHANGELOG.md
Add to Unreleased > Added:
- **Secret Sharing API (Phase 3 Complete)** (#182, #184, #185, #186)
- CRUD API for secrets with permission checks
- Share secrets with users or roles (read/write/admin permissions)
- Grant/revoke access endpoints
- Permission hierarchy enforcement (admin > write > read)
- Expiration support for temporary shares
- SecretAttachmentPolicy respects shares
- Integration tests: Secrets + Shares + Attachments
- OpenAPI documentation for Secret Management6. Tests (Pest)
Feature Tests - SecretAttachmentPolicy:
- User with read share can view attachment
- User with read share cannot upload attachment
- User with write share can upload attachment
- User with write share can delete attachment
- User without share cannot access attachment
Integration Tests:
- Complete workflow: Create → Share → Access → Revoke
- Permission escalation: read → write → admin
- Role-based sharing across multiple users
- Expiration enforcement across all endpoints
Total New Tests: ~15-20
✅ Acceptance Criteria
- SecretAttachmentPolicy updated for shares
- All integration tests passing (~20 tests)
- OpenAPI spec updated in contracts repo
- Documentation complete (guides + README)
- CHANGELOG.md updated with complete Phase 3 summary
- PHPStan level max passing
- Laravel Pint passing
- REUSE 3.3 compliant
- Issue Phase 3: Secret Sharing & Access Control (RBAC Integration) #182 can be closed (all sub-issues complete)
🔗 Dependencies
- Depends on:
- PHPStan: SecretController mixed type warnings from request->input() #184 (SecretController) - BLOCKED
- Phase 3: Secret Sharing & Access Control (RBAC Integration) #185 (SecretShareController) - BLOCKED
- ✅ Phase 2: File Attachments API (Upload/Download/Encryption) #175 (File Attachments) - Merged
- Blocks:
- Nothing! This is the final sub-issue
- Closes: Issue Phase 3: Secret Sharing & Access Control (RBAC Integration) #182 (Phase 3)
- Unblocks:
- enhancement: Add file upload to backend API for Secret attachments frontend#141 (File Upload UI)
- Phase 4 (Frontend Secret Vault UI)
📝 Technical Notes
Test Structure
describe('Secrets + Shares + Attachments Integration', function () {
test('user with read share can view but not upload attachments', function () {
$owner = User::factory()->create();
$sharedUser = User::factory()->create();
$secret = createTestSecret(['owner_id' => $owner->id]);
$attachment = createTestAttachment(['secret_id' => $secret->id]);
// Grant read permission
SecretShare::create([
'secret_id' => $secret->id,
'user_id' => $sharedUser->id,
'permission' => 'read',
'granted_by' => $owner->id,
'granted_at' => now(),
]);
// Can view attachment
$response = $this->actingAs($sharedUser)
->getJson("/api/v1/secrets/{$secret->id}/attachments/{$attachment->id}");
$response->assertOk();
// Cannot upload attachment
$response = $this->actingAs($sharedUser)
->postJson("/api/v1/secrets/{$secret->id}/attachments", [
'file' => UploadedFile::fake()->create('doc.pdf', 100),
]);
$response->assertForbidden();
});
});📝 PR Linking Instructions
When creating the PR:
Fixes #186
Closes #182- Do NOT start until PHPStan: SecretController mixed type warnings from request->input() #184 AND Phase 3: Secret Sharing & Access Control (RBAC Integration) #185 are merged
- This PR CLOSES Phase 3: Secret Sharing & Access Control (RBAC Integration) #182 (final sub-issue)
- Estimated LOC: ~250-300
Type: Sub-Issue (Backend + Documentation)
Priority: High
Estimated Effort: 2-3 days
Status: ⏸️ Blocked by #184, #185
Metadata
Metadata
Assignees
Type
Projects
Status
✅ Done