Metadata-Version: 2.4
Name: concinno-skills-auth
Version: 0.1.0
Summary: Unified credential, OAuth device-flow, and rotation skills for Concinno — one vault for all 20+ concinno-skills-* sub-packages.
Project-URL: Homepage, https://github.com/aiking931931/concinno
Project-URL: Issues, https://github.com/aiking931931/concinno/issues
Project-URL: Changelog, https://github.com/aiking931931/concinno/blob/main/projects/concinno-skills-auth/CHANGELOG.md
Author-email: "AI King (Chen-Xuan Wang)" <me@ai-king.dev>
License-Expression: Apache-2.0
License-File: LICENSE
Keywords: agent,concinno,credentials,device-code,keyring,oauth,secret-rotation,skills,vault
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Security :: Cryptography
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.10
Requires-Dist: concinno>=2.15.1
Requires-Dist: cryptography>=42
Requires-Dist: httpx>=0.27
Requires-Dist: keyring>=25
Provides-Extra: dev
Requires-Dist: mypy>=1.10; extra == 'dev'
Requires-Dist: pytest-cov>=5; extra == 'dev'
Requires-Dist: pytest>=8; extra == 'dev'
Requires-Dist: ruff>=0.7; extra == 'dev'
Description-Content-Type: text/markdown

# concinno-skills-auth

Unified credential, OAuth device-flow, and rotation skills for
[Concinno](https://pypi.org/project/concinno/). One vault for all 20+
`concinno-skills-*` sub-packages. Local-machine Fernet-encrypted vault
with OS-keyring master key + file fallback.

## Status

MVP (0.1.0) — three tools:

| Tool class       | Action surface                                  |
|:-----------------|:------------------------------------------------|
| `CredentialAuth` | list / get / set / delete / providers           |
| `OAuthFlow`      | initiate / complete / one_shot (RFC 8628 device-code grant) |
| `SecretRotate`   | rotate / rotate_all / revoke                    |

Ships OAuth device-code endpoints for **GitHub**, **Google**,
**Microsoft**, and a generic `custom` slot for any RFC 8628–compatible
provider. **Slack** does not support device flow — use
`CredentialAuth.set` with a `xoxb-...` bot token instead.

Twenty other providers are registered as static-token stores:
`anthropic` / `aws` / `azure` / `chroma` / `cohere` / `gcp` / `hubspot`
/ `intercom` / `mailchimp` / `notion` / `openai` / `pinecone` /
`salesforce` / `sendgrid` / `shopify` / `stripe` / `twilio` /
`typeform` / `weaviate` / `zendesk`.

## Install

```bash
pip install concinno-skills-auth
```

Dependencies: `concinno>=2.15.1`, `cryptography>=42`, `keyring>=25`,
`httpx>=0.27`.

## Vault

Location: `~/.concinno/vault/credentials.enc` (Fernet-encrypted).
Master key in the OS keyring (Windows Credential Locker / macOS
Keychain / Linux libsecret), falling back to
`~/.concinno/vault/.master-key` with `0o600` if no keyring backend is
available.

Per-mutation backup: last 5 ciphertext snapshots under
`~/.concinno/vault/backups/`.

See [`src/concinno_skills_auth/SECURITY.md`](src/concinno_skills_auth/SECURITY.md)
for the threat model and crypto choices.

## Usage via Concinno `ToolRegistry`

```python
import os
os.environ["CONCINNO_LOAD_PLUGINS"] = "1"

from concinno.tools.registry import get_default_registry

reg = get_default_registry()
reg.load_plugins()
assert {"CredentialAuth", "OAuthFlow", "SecretRotate"} <= set(
    reg.list_deferred()
)
```

## Direct Python

```python
from concinno_skills_auth import CredentialAuth, OAuthFlow, SecretRotate

# Store a GitHub personal access token
CredentialAuth().call(
    action="set",
    alias="github-main",
    provider="github",
    type="api_key",
    data={"api_key": "ghp_xxxxxxxxxxxxxxxxxxxx"},
    scopes=["repo", "read:user"],
)

# OAuth device-code flow (GitHub)
OAuthFlow().call(
    action="one_shot",
    provider="github",
    client_id="Iv1.your-oauth-app-id",
    scopes=["repo"],
    alias="github-device",
)

# Rotate
SecretRotate().call(
    action="rotate",
    alias="github-main",
    new_data={"api_key": "ghp_new_value"},
    reason="90-day policy",
)

# Emergency revoke — removes from vault + surfaces provider revoke URL
SecretRotate().call(action="revoke", alias="github-main", reason="token leaked")
```

All tools return `{"ok": True, ...}` or a structured payload on success,
`{"error": "..."}` on failure. No exceptions escape `call()`.

## Concurrency

All three tools set `is_concurrency_safe = False`. The vault is
file-backed with a cross-platform advisory lock (`fcntl` POSIX /
`msvcrt` Windows) around read-modify-write; the Concinno scheduler
will serialise calls to these tools automatically.

## Redaction

`CredentialAuth.call(action="get", alias=..., reveal=False)` returns a
redacted copy — each string in `entry["data"]` is replaced with
`<redacted N chars>`. Pass `reveal=True` to get the raw secret.

## Skill

The global skill at `~/.claude/skills/credentials/SKILL.md` wraps these
three tools into a conversational onboarding / rotation / emergency
flow. Triggers on phrases like "新 token", "OAuth 流程", "rotate",
"revoke". See the skill directory for `workflows.md` (three concrete
flows) and `providers.md` (per-provider URLs + scopes).

## License

Apache-2.0. See `LICENSE`.
