{
  "description": "GarageAdminToken is the Schema for the garageadmintokens API\nIt manages admin API tokens for Garage clusters",
  "properties": {
    "apiVersion": {
      "description": "APIVersion defines the versioned schema of this representation of an object.\nServers should convert recognized schemas to the latest internal value, and\nmay reject unrecognized values.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources",
      "type": [
        "string",
        "null"
      ]
    },
    "kind": {
      "description": "Kind is a string value representing the REST resource this object represents.\nServers may infer this from the endpoint the client submits requests to.\nCannot be updated.\nIn CamelCase.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
      "type": [
        "string",
        "null"
      ]
    },
    "metadata": {
      "type": [
        "object",
        "null"
      ]
    },
    "spec": {
      "additionalProperties": false,
      "description": "GarageAdminTokenSpec defines the desired state of GarageAdminToken.\n\nGarageAdminToken provisions secrets for accessing the Garage Admin HTTP API.\nAdmin tokens authenticate differently from S3 keys (GarageKey) — they use\nBearer token auth against the admin port (default 3903) instead of HMAC-SHA256.\n\nThe operator writes the token as an admin_token_file in Garage's TOML config.\nFile-based tokens always have full admin access; there is no scope restriction.\nTo create scoped tokens, use Garage's Admin API (CreateAdminToken) directly —\nthis resource is for provisioning the full-access operator/tooling token.",
      "properties": {
        "clusterRef": {
          "additionalProperties": false,
          "description": "ClusterRef references the GarageCluster this token belongs to",
          "properties": {
            "kubeConfigSecretRef": {
              "additionalProperties": false,
              "description": "KubeConfigSecretRef references a secret containing a kubeconfig for a remote Kubernetes cluster.\nOnly needed for multi-cluster federation where the GarageCluster lives in a different\nKubernetes cluster entirely (not just a different namespace).",
              "properties": {
                "key": {
                  "description": "The key of the secret to select from.  Must be a valid secret key.",
                  "type": "string"
                },
                "name": {
                  "default": "",
                  "description": "Name of the referent.\nThis field is effectively required, but due to backwards compatibility is\nallowed to be empty. Instances of this type with an empty value here are\nalmost certainly wrong.\nMore info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names",
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "optional": {
                  "description": "Specify whether the Secret or its key must be defined",
                  "type": [
                    "boolean",
                    "null"
                  ]
                }
              },
              "required": [
                "key"
              ],
              "type": [
                "object",
                "null"
              ],
              "x-kubernetes-map-type": "atomic"
            },
            "name": {
              "description": "Name of the GarageCluster resource.",
              "type": "string"
            },
            "namespace": {
              "description": "Namespace of the GarageCluster. Defaults to the referencing resource's namespace.\nCross-namespace references require a GarageReferenceGrant in the target namespace.\nNot supported on GarageNode.",
              "type": [
                "string",
                "null"
              ]
            }
          },
          "required": [
            "name"
          ],
          "type": "object"
        },
        "expiresAt": {
          "description": "ExpiresAt sets when this token should be rotated.\nThe operator tracks this and sets the TokenExpired condition when the date passes,\nbut does NOT automatically rotate or revoke the token — rotation requires manual action\n(update or delete the GarageAdminToken resource). Use NeverExpires to suppress expiry tracking.\nMutually exclusive with NeverExpires.",
          "format": "date-time",
          "type": [
            "string",
            "null"
          ]
        },
        "name": {
          "description": "Name is a friendly name for this admin token\nIf not set, metadata.name is used",
          "type": [
            "string",
            "null"
          ]
        },
        "neverExpires": {
          "description": "NeverExpires sets the token to never expire.\nMutually exclusive with ExpiresAt.",
          "type": [
            "boolean",
            "null"
          ]
        },
        "secretTemplate": {
          "additionalProperties": false,
          "description": "SecretTemplate configures how the secret containing the token is generated",
          "properties": {
            "annotations": {
              "additionalProperties": {
                "type": "string"
              },
              "description": "Annotations to add to the secret",
              "type": [
                "object",
                "null"
              ]
            },
            "endpointKey": {
              "default": "admin-endpoint",
              "description": "EndpointKey is the key name for the admin endpoint",
              "type": [
                "string",
                "null"
              ]
            },
            "includeEndpoint": {
              "description": "IncludeEndpoint includes the admin API endpoint in the secret\nDefaults to true if not specified",
              "type": [
                "boolean",
                "null"
              ]
            },
            "labels": {
              "additionalProperties": {
                "type": "string"
              },
              "description": "Labels to add to the secret",
              "type": [
                "object",
                "null"
              ]
            },
            "name": {
              "description": "Name is the name of the secret to create\nDefaults to the GarageAdminToken name",
              "type": [
                "string",
                "null"
              ]
            },
            "tokenKey": {
              "default": "admin-token",
              "description": "TokenKey is the key name for the admin token in the secret",
              "type": [
                "string",
                "null"
              ]
            }
          },
          "type": [
            "object",
            "null"
          ]
        }
      },
      "required": [
        "clusterRef"
      ],
      "type": "object"
    },
    "status": {
      "additionalProperties": false,
      "description": "GarageAdminTokenStatus defines the observed state of GarageAdminToken",
      "properties": {
        "conditions": {
          "description": "Conditions represent the current state",
          "items": {
            "additionalProperties": false,
            "description": "Condition contains details for one aspect of the current state of this API Resource.",
            "properties": {
              "lastTransitionTime": {
                "description": "lastTransitionTime is the last time the condition transitioned from one status to another.\nThis should be when the underlying condition changed.  If that is not known, then using the time when the API field changed is acceptable.",
                "format": "date-time",
                "type": "string"
              },
              "message": {
                "description": "message is a human readable message indicating details about the transition.\nThis may be an empty string.",
                "maxLength": 32768,
                "type": "string"
              },
              "observedGeneration": {
                "description": "observedGeneration represents the .metadata.generation that the condition was set based upon.\nFor instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date\nwith respect to the current state of the instance.",
                "format": "int64",
                "minimum": 0,
                "type": [
                  "integer",
                  "null"
                ]
              },
              "reason": {
                "description": "reason contains a programmatic identifier indicating the reason for the condition's last transition.\nProducers of specific condition types may define expected values and meanings for this field,\nand whether the values are considered a guaranteed API.\nThe value should be a CamelCase string.\nThis field may not be empty.",
                "maxLength": 1024,
                "minLength": 1,
                "pattern": "^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$",
                "type": "string"
              },
              "status": {
                "description": "status of the condition, one of True, False, Unknown.",
                "enum": [
                  "True",
                  "False",
                  "Unknown"
                ],
                "type": "string"
              },
              "type": {
                "description": "type of condition in CamelCase or in foo.example.com/CamelCase.",
                "maxLength": 316,
                "pattern": "^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$",
                "type": "string"
              }
            },
            "required": [
              "lastTransitionTime",
              "message",
              "reason",
              "status",
              "type"
            ],
            "type": "object"
          },
          "type": [
            "array",
            "null"
          ],
          "x-kubernetes-list-map-keys": [
            "type"
          ],
          "x-kubernetes-list-type": "map"
        },
        "expiresAt": {
          "description": "ExpiresAt is when this token expires (if set)",
          "format": "date-time",
          "type": [
            "string",
            "null"
          ]
        },
        "observedGeneration": {
          "description": "ObservedGeneration is the last observed generation",
          "format": "int64",
          "type": [
            "integer",
            "null"
          ]
        },
        "phase": {
          "description": "Phase represents the current phase",
          "enum": [
            "Pending",
            "Creating",
            "Ready",
            "Deleting",
            "Failed",
            "Expired",
            "Unknown"
          ],
          "type": [
            "string",
            "null"
          ]
        },
        "secretRef": {
          "additionalProperties": false,
          "description": "SecretRef references the created secret",
          "properties": {
            "name": {
              "description": "name is unique within a namespace to reference a secret resource.",
              "type": [
                "string",
                "null"
              ]
            },
            "namespace": {
              "description": "namespace defines the space within which the secret name must be unique.",
              "type": [
                "string",
                "null"
              ]
            }
          },
          "type": [
            "object",
            "null"
          ],
          "x-kubernetes-map-type": "atomic"
        },
        "tokenId": {
          "description": "TokenID is the Garage-assigned token ID (first 8 chars)",
          "type": [
            "string",
            "null"
          ]
        }
      },
      "type": [
        "object",
        "null"
      ]
    }
  },
  "required": [
    "spec"
  ],
  "type": "object"
}