test fixes and new product advisories work
This commit is contained in:
308
docs/modules/doctor/architecture.md
Normal file
308
docs/modules/doctor/architecture.md
Normal file
@@ -0,0 +1,308 @@
|
||||
# Doctor Architecture
|
||||
|
||||
> Module: Doctor
|
||||
> Sprint: SPRINT_0127_001_0002_oci_registry_compatibility
|
||||
|
||||
Stella Doctor is a diagnostic framework for validating system health, configuration, and integration connectivity across the StellaOps platform.
|
||||
|
||||
## 1) Overview
|
||||
|
||||
Doctor provides a plugin-based diagnostic system that enables:
|
||||
- **Health checks** for all platform components
|
||||
- **Integration validation** for external systems (registries, SCM, CI, secrets)
|
||||
- **Configuration verification** before deployment
|
||||
- **Capability probing** for feature compatibility
|
||||
- **Evidence collection** for troubleshooting and compliance
|
||||
|
||||
## 2) Plugin Architecture
|
||||
|
||||
### Core Interfaces
|
||||
|
||||
```csharp
|
||||
public interface IDoctorPlugin
|
||||
{
|
||||
string PluginId { get; }
|
||||
string DisplayName { get; }
|
||||
string Category { get; }
|
||||
Version Version { get; }
|
||||
|
||||
IEnumerable<IDoctorCheck> GetChecks();
|
||||
Task InitializeAsync(DoctorPluginContext context, CancellationToken ct);
|
||||
}
|
||||
|
||||
public interface IDoctorCheck
|
||||
{
|
||||
string CheckId { get; }
|
||||
string Name { get; }
|
||||
string Description { get; }
|
||||
DoctorSeverity DefaultSeverity { get; }
|
||||
IReadOnlyList<string> Tags { get; }
|
||||
TimeSpan EstimatedDuration { get; }
|
||||
|
||||
bool CanRun(DoctorPluginContext context);
|
||||
Task<CheckResult> RunAsync(DoctorPluginContext context, CancellationToken ct);
|
||||
}
|
||||
```
|
||||
|
||||
### Plugin Context
|
||||
|
||||
```csharp
|
||||
public sealed class DoctorPluginContext
|
||||
{
|
||||
public IServiceProvider Services { get; }
|
||||
public IConfiguration Configuration { get; }
|
||||
public TimeProvider TimeProvider { get; }
|
||||
public ILogger Logger { get; }
|
||||
public string EnvironmentName { get; }
|
||||
public IReadOnlyDictionary<string, object> PluginConfig { get; }
|
||||
}
|
||||
```
|
||||
|
||||
### Check Results
|
||||
|
||||
```csharp
|
||||
public sealed record CheckResult
|
||||
{
|
||||
public DoctorSeverity Severity { get; init; }
|
||||
public string Diagnosis { get; init; }
|
||||
public Evidence Evidence { get; init; }
|
||||
public IReadOnlyList<string> LikelyCauses { get; init; }
|
||||
public Remediation? Remediation { get; init; }
|
||||
public string? VerificationCommand { get; init; }
|
||||
}
|
||||
|
||||
public enum DoctorSeverity
|
||||
{
|
||||
Pass, // Check succeeded
|
||||
Info, // Informational (no action needed)
|
||||
Warn, // Warning (degraded but functional)
|
||||
Fail, // Failure (requires action)
|
||||
Skip // Check skipped (preconditions not met)
|
||||
}
|
||||
```
|
||||
|
||||
## 3) Built-in Plugins
|
||||
|
||||
### IntegrationPlugin
|
||||
|
||||
Validates external system connectivity and capabilities.
|
||||
|
||||
**Check Catalog:**
|
||||
|
||||
| Check ID | Name | Severity | Description |
|
||||
|----------|------|----------|-------------|
|
||||
| `check.integration.oci.credentials` | OCI Registry Credentials | Fail | Validate registry authentication |
|
||||
| `check.integration.oci.pull` | OCI Registry Pull Authorization | Fail | Verify pull permissions |
|
||||
| `check.integration.oci.push` | OCI Registry Push Authorization | Fail | Verify push permissions |
|
||||
| `check.integration.oci.referrers` | OCI Registry Referrers API | Warn | Check OCI 1.1 referrers support |
|
||||
| `check.integration.oci.capabilities` | OCI Registry Capability Matrix | Info | Probe all registry capabilities |
|
||||
|
||||
See [Registry Diagnostic Checks](./registry-checks.md) for detailed documentation.
|
||||
|
||||
### ConfigurationPlugin
|
||||
|
||||
Validates platform configuration.
|
||||
|
||||
| Check ID | Name | Severity | Description |
|
||||
|----------|------|----------|-------------|
|
||||
| `check.config.database` | Database Connection | Fail | Verify database connectivity |
|
||||
| `check.config.secrets` | Secrets Provider | Fail | Verify secrets access |
|
||||
| `check.config.tls` | TLS Configuration | Warn | Validate TLS certificates |
|
||||
|
||||
### HealthPlugin
|
||||
|
||||
Validates platform component health.
|
||||
|
||||
| Check ID | Name | Severity | Description |
|
||||
|----------|------|----------|-------------|
|
||||
| `check.health.api` | API Health | Fail | Verify API endpoints |
|
||||
| `check.health.worker` | Worker Health | Fail | Verify background workers |
|
||||
| `check.health.storage` | Storage Health | Fail | Verify storage backends |
|
||||
|
||||
## 4) Check Patterns
|
||||
|
||||
### Non-Destructive Probing
|
||||
|
||||
Registry checks use non-destructive operations:
|
||||
|
||||
```csharp
|
||||
// Pull check: HEAD request only (no data transfer)
|
||||
var response = await client.SendAsync(new HttpRequestMessage(HttpMethod.Head, manifestUrl), ct);
|
||||
|
||||
// Push check: Start upload then immediately cancel
|
||||
var uploadResponse = await client.PostAsync(uploadsUrl, null, ct);
|
||||
if (uploadResponse.StatusCode == HttpStatusCode.Accepted)
|
||||
{
|
||||
var location = uploadResponse.Headers.Location;
|
||||
await client.DeleteAsync(location, ct); // Cancel upload
|
||||
}
|
||||
```
|
||||
|
||||
### Capability Detection
|
||||
|
||||
Registry capability probing sequence:
|
||||
|
||||
```
|
||||
1. GET /v2/ → Extract OCI-Distribution-API-Version header
|
||||
2. GET /v2/{repo}/referrers/{digest} → Check referrers API support
|
||||
3. POST /v2/{repo}/blobs/uploads/ → Check chunked upload support
|
||||
└─ DELETE {location} → Cancel upload session
|
||||
4. POST /v2/{repo}/blobs/uploads/?mount=...&from=... → Check cross-repo mount
|
||||
5. OPTIONS /v2/{repo}/manifests/{ref} → Check delete support (Allow header)
|
||||
6. OPTIONS /v2/{repo}/blobs/{digest} → Check blob delete support
|
||||
```
|
||||
|
||||
### Evidence Collection
|
||||
|
||||
All checks collect structured evidence:
|
||||
|
||||
```csharp
|
||||
var result = CheckResultBuilder.Create(check)
|
||||
.Pass("Registry authentication successful")
|
||||
.WithEvidence(eb => eb
|
||||
.Add("registry_url", registryUrl)
|
||||
.Add("auth_method", "bearer")
|
||||
.Add("response_time_ms", elapsed.TotalMilliseconds.ToString("F0"))
|
||||
.AddSensitive("token_preview", RedactToken(token)))
|
||||
.Build();
|
||||
```
|
||||
|
||||
### Credential Redaction
|
||||
|
||||
Sensitive values are automatically redacted:
|
||||
|
||||
```csharp
|
||||
// Redact to first 2 + last 2 characters
|
||||
private static string Redact(string? value)
|
||||
{
|
||||
if (string.IsNullOrEmpty(value) || value.Length <= 4)
|
||||
return "****";
|
||||
return $"{value[..2]}...{value[^2..]}";
|
||||
}
|
||||
// "mysecretpassword" → "my...rd"
|
||||
```
|
||||
|
||||
## 5) CLI Integration
|
||||
|
||||
```bash
|
||||
# Run all checks
|
||||
stella doctor
|
||||
|
||||
# Run checks by tag
|
||||
stella doctor --tag registry
|
||||
stella doctor --tag configuration
|
||||
|
||||
# Run specific check
|
||||
stella doctor --check check.integration.oci.referrers
|
||||
|
||||
# Output formats
|
||||
stella doctor --format table # Default: human-readable
|
||||
stella doctor --format json # Machine-readable
|
||||
stella doctor --format sarif # SARIF for CI integration
|
||||
|
||||
# Verbosity
|
||||
stella doctor --verbose # Include evidence details
|
||||
stella doctor --quiet # Only show failures
|
||||
|
||||
# Filtering by severity
|
||||
stella doctor --min-severity warn # Skip info/pass
|
||||
```
|
||||
|
||||
## 6) Extensibility
|
||||
|
||||
### Creating a Custom Check
|
||||
|
||||
```csharp
|
||||
public sealed class MyCustomCheck : IDoctorCheck
|
||||
{
|
||||
public string CheckId => "check.custom.mycheck";
|
||||
public string Name => "My Custom Check";
|
||||
public string Description => "Validates custom integration";
|
||||
public DoctorSeverity DefaultSeverity => DoctorSeverity.Fail;
|
||||
public IReadOnlyList<string> Tags => ["custom", "integration"];
|
||||
public TimeSpan EstimatedDuration => TimeSpan.FromSeconds(5);
|
||||
|
||||
public bool CanRun(DoctorPluginContext context)
|
||||
{
|
||||
// Return false if preconditions not met
|
||||
return context.Configuration["Custom:Enabled"] == "true";
|
||||
}
|
||||
|
||||
public async Task<CheckResult> RunAsync(DoctorPluginContext context, CancellationToken ct)
|
||||
{
|
||||
var builder = CheckResultBuilder.Create(this);
|
||||
|
||||
try
|
||||
{
|
||||
// Perform check logic
|
||||
var result = await ValidateAsync(context, ct);
|
||||
|
||||
if (result.Success)
|
||||
{
|
||||
return builder
|
||||
.Pass("Custom validation successful")
|
||||
.WithEvidence(eb => eb.Add("detail", result.Detail))
|
||||
.Build();
|
||||
}
|
||||
|
||||
return builder
|
||||
.Fail("Custom validation failed")
|
||||
.WithLikelyCause("Configuration is invalid")
|
||||
.WithRemediation(rb => rb
|
||||
.AddManualStep(1, "Check configuration", "Verify Custom:Setting is correct")
|
||||
.WithRunbookUrl("https://docs.stella-ops.org/runbooks/custom-check"))
|
||||
.Build();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return builder
|
||||
.Fail($"Check failed with error: {ex.Message}")
|
||||
.WithEvidence(eb => eb.Add("exception_type", ex.GetType().Name))
|
||||
.Build();
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Creating a Custom Plugin
|
||||
|
||||
```csharp
|
||||
public sealed class MyCustomPlugin : IDoctorPlugin
|
||||
{
|
||||
public string PluginId => "custom";
|
||||
public string DisplayName => "Custom Checks";
|
||||
public string Category => "Integration";
|
||||
public Version Version => new(1, 0, 0);
|
||||
|
||||
public IEnumerable<IDoctorCheck> GetChecks()
|
||||
{
|
||||
yield return new MyCustomCheck();
|
||||
yield return new AnotherCustomCheck();
|
||||
}
|
||||
|
||||
public Task InitializeAsync(DoctorPluginContext context, CancellationToken ct)
|
||||
{
|
||||
// Optional initialization
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 7) Telemetry
|
||||
|
||||
Doctor emits metrics and traces for observability:
|
||||
|
||||
**Metrics:**
|
||||
- `doctor_check_duration_seconds{check_id, severity}` - Check execution time
|
||||
- `doctor_check_results_total{check_id, severity}` - Result counts
|
||||
- `doctor_plugin_load_duration_seconds{plugin_id}` - Plugin initialization time
|
||||
|
||||
**Traces:**
|
||||
- `doctor.run` - Full doctor run span
|
||||
- `doctor.check.{check_id}` - Individual check spans with evidence as attributes
|
||||
|
||||
## 8) Related Documentation
|
||||
|
||||
- [Registry Diagnostic Checks](./registry-checks.md)
|
||||
- [Registry Compatibility Runbook](../../runbooks/registry-compatibility.md)
|
||||
- [Registry Referrer Troubleshooting](../../runbooks/registry-referrer-troubleshooting.md)
|
||||
366
docs/modules/doctor/registry-checks.md
Normal file
366
docs/modules/doctor/registry-checks.md
Normal file
@@ -0,0 +1,366 @@
|
||||
# Registry Diagnostic Checks
|
||||
|
||||
> Module: Doctor
|
||||
> Plugin: IntegrationPlugin
|
||||
> Sprint: SPRINT_0127_001_0002_oci_registry_compatibility
|
||||
|
||||
This document covers the OCI registry diagnostic checks available in Stella Doctor for validating registry connectivity, capabilities, and authorization.
|
||||
|
||||
## Overview
|
||||
|
||||
StellaOps Doctor includes comprehensive registry diagnostics to verify that configured OCI registries are properly accessible and support the features required for secure software supply chain operations. These checks are part of the `IntegrationPlugin` and can be run individually or as a group using the `registry` tag.
|
||||
|
||||
## Quick Start
|
||||
|
||||
```bash
|
||||
# Run all registry checks
|
||||
stella doctor --tag registry
|
||||
|
||||
# Run a specific check
|
||||
stella doctor --check check.integration.oci.referrers
|
||||
|
||||
# Export results as JSON
|
||||
stella doctor --tag registry --format json --output registry-health.json
|
||||
|
||||
# Run with verbose output
|
||||
stella doctor --tag registry --verbose
|
||||
```
|
||||
|
||||
## Available Checks
|
||||
|
||||
### check.integration.oci.credentials
|
||||
|
||||
**Purpose:** Validate registry credential configuration and authentication.
|
||||
|
||||
| Property | Value |
|
||||
|----------|-------|
|
||||
| Name | OCI Registry Credentials |
|
||||
| Default Severity | Fail |
|
||||
| Tags | `registry`, `oci`, `credentials`, `secrets`, `auth` |
|
||||
| Estimated Duration | 5 seconds |
|
||||
|
||||
**What it checks:**
|
||||
1. Credential configuration (username/password, bearer token, or anonymous)
|
||||
2. Authentication against the `/v2/` endpoint
|
||||
3. OAuth2 token exchange for registries requiring it
|
||||
4. Credential validity and format
|
||||
|
||||
**Evidence collected:**
|
||||
- `registry_url` - Target registry URL
|
||||
- `auth_method` - Authentication method (basic, bearer, anonymous)
|
||||
- `username` - Username (if configured)
|
||||
- `credentials_valid` - Whether authentication succeeded
|
||||
- `auth_challenge` - WWW-Authenticate header if present
|
||||
|
||||
**Pass criteria:**
|
||||
- Credentials are properly configured
|
||||
- Authentication succeeds against `/v2/` endpoint
|
||||
|
||||
**Fail scenarios:**
|
||||
- Missing required credentials (username without password)
|
||||
- Invalid credentials (401 Unauthorized)
|
||||
- Network or TLS errors
|
||||
|
||||
---
|
||||
|
||||
### check.integration.oci.pull
|
||||
|
||||
**Purpose:** Verify pull authorization for the configured test repository.
|
||||
|
||||
| Property | Value |
|
||||
|----------|-------|
|
||||
| Name | OCI Registry Pull Authorization |
|
||||
| Default Severity | Fail |
|
||||
| Tags | `registry`, `oci`, `pull`, `authorization` |
|
||||
| Estimated Duration | 5 seconds |
|
||||
|
||||
**What it checks:**
|
||||
1. HEAD request to manifest endpoint (non-destructive)
|
||||
2. Authorization for pull operations
|
||||
3. Image/tag existence
|
||||
|
||||
**Evidence collected:**
|
||||
- `registry_url` - Target registry URL
|
||||
- `test_repository` - Repository used for testing
|
||||
- `test_tag` - Tag used for testing
|
||||
- `pull_authorized` - Whether pull is authorized
|
||||
- `manifest_digest` - Manifest digest if successful
|
||||
- `http_status` - HTTP status code
|
||||
|
||||
**Pass criteria:**
|
||||
- HEAD request to manifest returns 200 OK
|
||||
- Manifest digest is returned
|
||||
|
||||
**Fail scenarios:**
|
||||
- 401 Unauthorized: Invalid credentials
|
||||
- 403 Forbidden: Valid credentials but no pull permission
|
||||
- Info (not fail) for 404: Test image not found (can't verify)
|
||||
|
||||
---
|
||||
|
||||
### check.integration.oci.push
|
||||
|
||||
**Purpose:** Verify push authorization for the configured test repository.
|
||||
|
||||
| Property | Value |
|
||||
|----------|-------|
|
||||
| Name | OCI Registry Push Authorization |
|
||||
| Default Severity | Fail |
|
||||
| Tags | `registry`, `oci`, `push`, `authorization` |
|
||||
| Estimated Duration | 10 seconds |
|
||||
|
||||
**What it checks:**
|
||||
1. Initiates blob upload via POST (non-destructive)
|
||||
2. Immediately cancels the upload session
|
||||
3. Verifies push authorization
|
||||
|
||||
**Evidence collected:**
|
||||
- `registry_url` - Target registry URL
|
||||
- `test_repository` - Repository used for testing
|
||||
- `push_authorized` - Whether push is authorized
|
||||
- `upload_session_cancelled` - Whether cleanup succeeded
|
||||
- `http_status` - HTTP status code
|
||||
- `credentials_valid` - Whether credentials are valid (for 403)
|
||||
|
||||
**Pass criteria:**
|
||||
- POST to blob uploads returns 202 Accepted
|
||||
- Upload session is successfully cancelled
|
||||
|
||||
**Fail scenarios:**
|
||||
- 401 Unauthorized: Invalid credentials
|
||||
- 403 Forbidden: Valid credentials but no push permission
|
||||
|
||||
**Non-destructive design:**
|
||||
This check initiates a blob upload session but immediately cancels it via DELETE. No data is actually pushed to the registry.
|
||||
|
||||
---
|
||||
|
||||
### check.integration.oci.referrers
|
||||
|
||||
**Purpose:** Verify OCI 1.1 referrers API support for artifact linking.
|
||||
|
||||
| Property | Value |
|
||||
|----------|-------|
|
||||
| Name | OCI Registry Referrers API Support |
|
||||
| Default Severity | Warn |
|
||||
| Tags | `registry`, `oci`, `referrers`, `oci-1.1` |
|
||||
| Estimated Duration | 10 seconds |
|
||||
|
||||
**What it checks:**
|
||||
1. Resolves manifest digest for test image
|
||||
2. Probes the referrers API endpoint
|
||||
3. Determines if native API or fallback is required
|
||||
|
||||
**Evidence collected:**
|
||||
- `registry_url` - Target registry URL
|
||||
- `referrers_supported` - Whether referrers API is supported
|
||||
- `fallback_required` - Whether tag-based fallback is needed
|
||||
- `oci_version` - OCI-Distribution-API-Version header
|
||||
- `referrers_count` - Number of referrers found (if any)
|
||||
|
||||
**Pass criteria:**
|
||||
- Referrers endpoint returns 200 OK with OCI index
|
||||
- Or returns 404 with OCI index content (empty referrers)
|
||||
|
||||
**Warn scenarios (not Fail):**
|
||||
- 404 without OCI index: API not supported, fallback required
|
||||
- 405 Method Not Allowed: API not implemented
|
||||
|
||||
The severity is Warn (not Fail) because StellaOps automatically uses tag-based fallback discovery when the referrers API is unavailable.
|
||||
|
||||
---
|
||||
|
||||
### check.integration.oci.capabilities
|
||||
|
||||
**Purpose:** Comprehensive registry capability matrix detection.
|
||||
|
||||
| Property | Value |
|
||||
|----------|-------|
|
||||
| Name | OCI Registry Capability Matrix |
|
||||
| Default Severity | Info |
|
||||
| Tags | `registry`, `oci`, `capabilities`, `compatibility` |
|
||||
| Estimated Duration | 30 seconds |
|
||||
|
||||
**What it checks:**
|
||||
1. OCI Distribution version (via headers)
|
||||
2. Referrers API support
|
||||
3. Chunked upload support
|
||||
4. Cross-repository blob mounting
|
||||
5. Manifest delete support
|
||||
6. Blob delete support
|
||||
|
||||
**Evidence collected:**
|
||||
- `registry_url` - Target registry URL
|
||||
- `distribution_version` - OCI/Docker distribution version
|
||||
- `supports_referrers_api` - true/false/unknown
|
||||
- `supports_chunked_upload` - true/false/unknown
|
||||
- `supports_cross_repo_mount` - true/false/unknown
|
||||
- `supports_manifest_delete` - true/false/unknown
|
||||
- `supports_blob_delete` - true/false/unknown
|
||||
- `capability_score` - Summary (e.g., "5/6")
|
||||
|
||||
**Severity logic:**
|
||||
- Pass: All capabilities supported
|
||||
- Info: Some non-critical capabilities missing
|
||||
- Warn: Referrers API not supported (critical for StellaOps)
|
||||
|
||||
---
|
||||
|
||||
## Configuration
|
||||
|
||||
Registry checks use the following configuration keys:
|
||||
|
||||
```yaml
|
||||
OCI:
|
||||
RegistryUrl: "https://registry.example.com"
|
||||
Username: "service-account"
|
||||
Password: "secret" # Or use PasswordSecretRef
|
||||
Token: "bearer-token" # Alternative to username/password
|
||||
TestRepository: "stellaops/test" # Default: library/alpine
|
||||
TestTag: "latest" # Default: latest
|
||||
```
|
||||
|
||||
### Environment Variables
|
||||
|
||||
```bash
|
||||
export OCI__RegistryUrl="https://registry.example.com"
|
||||
export OCI__Username="service-account"
|
||||
export OCI__Password="secret"
|
||||
export OCI__TestRepository="stellaops/test"
|
||||
export OCI__TestTag="latest"
|
||||
```
|
||||
|
||||
## Registry Compatibility Matrix
|
||||
|
||||
| Registry | Version | Referrers API | Chunked Upload | Cross-Mount | Delete | Recommended |
|
||||
|----------|---------|---------------|----------------|-------------|--------|-------------|
|
||||
| **ACR** | Any | Native | Yes | Yes | Yes | Yes |
|
||||
| **ECR** | Any | Native | Yes | Yes | Yes | Yes |
|
||||
| **GCR/Artifact Registry** | Any | Native | Yes | Yes | Yes | Yes |
|
||||
| **Harbor** | 2.6+ | Native | Yes | Yes | Yes | Yes |
|
||||
| **Quay** | 3.12+ | Native | Yes | Yes | Yes | Yes |
|
||||
| **JFrog Artifactory** | 7.x+ | Native | Yes | Yes | Yes | Yes |
|
||||
| **GHCR** | Any | Fallback | Yes | Yes | Yes | With fallback |
|
||||
| **Docker Hub** | Any | Fallback | Yes | Limited | Limited | With fallback |
|
||||
| **registry:2** | 2.8+ | Fallback | Yes | Yes | Yes | For testing |
|
||||
| **Zot** | Any | Native | Yes | Yes | Yes | Yes |
|
||||
| **Distribution** | Edge | Partial | Yes | Yes | Yes | Yes |
|
||||
|
||||
### Legend
|
||||
- **Native**: Full OCI 1.1 referrers API support
|
||||
- **Fallback**: Requires tag-based discovery (`sha256-{digest}.*` tags)
|
||||
- **Partial**: Support varies by configuration
|
||||
|
||||
## Known Issues & Workarounds
|
||||
|
||||
### GHCR (GitHub Container Registry)
|
||||
|
||||
**Issue:** Referrers API not implemented (returns 404 without OCI index)
|
||||
|
||||
**Impact:** Slower artifact discovery, requires tag-based fallback
|
||||
|
||||
**Workaround:** StellaOps automatically detects this and uses fallback discovery. No action required.
|
||||
|
||||
**Tracking:** GitHub feature request pending
|
||||
|
||||
### Docker Hub
|
||||
|
||||
**Issue:** Rate limiting can affect capability probes
|
||||
|
||||
**Impact:** Probes may timeout or return 429
|
||||
|
||||
**Workaround:**
|
||||
- Use authenticated requests to increase rate limits
|
||||
- Configure retry with exponential backoff
|
||||
- Consider using a pull-through cache
|
||||
|
||||
### Harbor < 2.6
|
||||
|
||||
**Issue:** Referrers API not available in older versions
|
||||
|
||||
**Impact:** Requires tag-based fallback
|
||||
|
||||
**Workaround:** Upgrade to Harbor 2.6+ for native referrers API support
|
||||
|
||||
### ACR with CMK Encryption
|
||||
|
||||
**Issue:** Customer-managed key encrypted registries may use tag fallback
|
||||
|
||||
**Impact:** Slightly slower referrer discovery
|
||||
|
||||
**Workaround:** Automatic fallback detection handles this transparently
|
||||
|
||||
**Reference:** [Azure Container Registry CMK Documentation](https://learn.microsoft.com/azure/container-registry/)
|
||||
|
||||
## Interpreting Results
|
||||
|
||||
### Healthy Registry Output
|
||||
|
||||
```
|
||||
Registry Checks Summary
|
||||
=======================
|
||||
|
||||
check.integration.oci.credentials PASS Credentials valid for registry.example.com
|
||||
check.integration.oci.pull PASS Pull authorized (sha256:abc123...)
|
||||
check.integration.oci.push PASS Push authorization verified
|
||||
check.integration.oci.referrers PASS Referrers API supported (OCI 1.1)
|
||||
check.integration.oci.capabilities PASS Full capability support (6/6)
|
||||
|
||||
Overall: 5 passed, 0 warnings, 0 failures
|
||||
```
|
||||
|
||||
### Registry with Fallback Required
|
||||
|
||||
```
|
||||
Registry Checks Summary
|
||||
=======================
|
||||
|
||||
check.integration.oci.credentials PASS Credentials valid for ghcr.io
|
||||
check.integration.oci.pull PASS Pull authorized (sha256:def456...)
|
||||
check.integration.oci.push PASS Push authorization verified
|
||||
check.integration.oci.referrers WARN Referrers API not supported (using fallback)
|
||||
check.integration.oci.capabilities INFO Partial capability support (4/6)
|
||||
|
||||
Overall: 3 passed, 1 warning, 1 info, 0 failures
|
||||
|
||||
Recommendations:
|
||||
- Referrers API: StellaOps will use tag-based fallback automatically
|
||||
- Consider upgrading to a registry with OCI 1.1 support for better performance
|
||||
```
|
||||
|
||||
## Remediation Steps
|
||||
|
||||
### Invalid Credentials (401)
|
||||
|
||||
1. Verify username and password are correct
|
||||
2. Check if credentials have expired
|
||||
3. For OAuth2 registries, ensure token refresh is working
|
||||
4. Test with docker CLI: `docker login <registry>`
|
||||
|
||||
### No Permission (403)
|
||||
|
||||
1. Verify the service account has required permissions
|
||||
2. For pull: Reader/Viewer role is typically sufficient
|
||||
3. For push: Contributor/Writer role is required
|
||||
4. Check repository-level permissions (some registries have repo-specific ACLs)
|
||||
|
||||
### Referrers API Not Supported
|
||||
|
||||
1. Check registry version against compatibility matrix
|
||||
2. Upgrade registry if possible (Harbor 2.6+, Quay 3.12+)
|
||||
3. If upgrade not possible, StellaOps will use fallback automatically
|
||||
4. Monitor for performance impact with large artifact counts
|
||||
|
||||
### Network/TLS Errors
|
||||
|
||||
1. Verify network connectivity: `curl -v https://<registry>/v2/`
|
||||
2. Check TLS certificate validity
|
||||
3. For self-signed certs, configure trust or use `--insecure` (not recommended for production)
|
||||
4. Check firewall rules and proxy configuration
|
||||
|
||||
## Related Documentation
|
||||
|
||||
- [Registry Compatibility Quick Reference](../../runbooks/registry-compatibility.md)
|
||||
- [Registry Referrer Troubleshooting](../../runbooks/registry-referrer-troubleshooting.md)
|
||||
- [Export Center Registry Compatibility](../export-center/registry-compatibility.md)
|
||||
- [Doctor Architecture](./architecture.md)
|
||||
Reference in New Issue
Block a user